我正在努力在延迟,带宽和吞吐量之间划清界限.
有人可以用简单的术语和简单的例子来解释我吗?
我正在考虑制作网络游戏.我对此有点新意,并且已经遇到了很多问题,试图为航位推算和网络延迟制定一个好的计划,所以我很想看到关于这个主题的一些好的文献.我将描述我考虑过的方法.
最初,我只是将玩家的输入发送到服务器,在那里进行模拟,并向所有玩家广播游戏状态的变化.这使作弊变得困难,但是在高延迟下,事情有点难以控制,因为你不会立即看到自己行为的结果.
这篇GamaSutra文章提供了一个解决方案,通过在客户端上进行模拟,可以节省带宽并使本地输入看起来更流畅,但它似乎可以防止窗外作弊.此外,当玩家开始操纵环境,推动岩石之类的时候,我不知道该怎么办.这些先前中立的对象将暂时成为客户端发送PDU所需的对象,或者可能是多个玩家同时执行的对象.谁的PDU会赢?每个玩家何时停止双重跟踪物体(与死亡计算版本进行比较)?天堂禁止两名球员参加相扑比赛(例如开始互相推进).
这个gamedev.net位显示gamasutra解决方案不合适,但描述了一种不能真正修复我的协作巨石推动示例的不同方法.我发现的大多数其他东西都是针对射手的.我希望看到一些更适合像SNES Zelda这样的游戏的东西,但需要更多的物理/动力.
https://www.w3.org/TR/resource-hints/
如果我理解正确,两者都用于启动早期连接以便以后更快地加载资源.
预连接正在做"更多".
除了更好的浏览器支持外,有没有理由在预连接上使用dns-prefetch?我也看到网站在相同的链接标签上使用rel,以便尽可能使用预连接,如果没有,则回退到dns-prefetch.
<head>
<link
rel="dns-prefetch preconnect"
href="https://fonts.gstatic.com"
crossorigin
>
</head>
Run Code Online (Sandbox Code Playgroud) 我正在使用BlockingQueue:s(尝试使用ArrayBlockingQueue和LinkedBlockingQueue)在我正在处理的应用程序中的不同线程之间传递对象.性能和延迟在这个应用程序中相对重要,所以我很好奇使用BlockingQueue在两个线程之间传递对象需要多长时间.为了衡量这一点,我写了一个简单的程序,有两个线程(一个消费者和一个生产者),我让生产者将时间戳(使用System.nanoTime())传递给消费者,参见下面的代码.
我记得在某个论坛上的某个地方读过,对于试过这个的人来说花了大约10微秒(不知道操作系统和硬件是什么),所以当我花了大约30微秒时,我并不感到惊讶Windows 7机箱(英特尔E7500核心2双核CPU,2.93GHz),同时在后台运行许多其他应用程序.然而,当我在速度更快的Linux服务器(两个Intel X5677 3.46GHz四核CPU,运行Debian 5和内核2.6.26-2-amd64)上进行相同的测试时,我感到非常惊讶.我预计延迟会低于我的Windows框,但相反它会高得多 - 约75 - 100微秒!两个测试都是使用Sun的Hotspot JVM版本1.6.0-23完成的.
有没有其他人在Linux上做过类似的测试?或者有人知道为什么Linux上的速度会慢得多(硬件更好),与Windows相比,Linux上的线程切换是否会慢得多?如果是这种情况,看起来Windows实际上更适合某种应用程序.任何帮助我理解相对较高的数字的帮助都非常感谢.
编辑:
在DaveC的评论之后,我还做了一个测试,我将JVM(在Linux机器上)限制为单个核心(即在同一核心上运行的所有线程).这大大改变了结果 - 延迟降至20微秒以下,即优于Windows机器上的结果.我还做了一些测试,我将生产者线程限制为一个核心,将消费者线程限制为另一个核心(尝试将它们放在同一个套接字和不同的套接字上),但这似乎没有帮助 - 延迟仍然是〜75微秒.顺便说一句,这个测试应用程序几乎就是我在执行测试时在机器上运行的所有应用程序.
有谁知道这些结果是否有意义?如果生产者和消费者在不同的核心上运行,它真的应该慢得多吗?任何输入都非常感谢.
再次编辑(1月6日):
我尝试对代码和运行环境进行不同的更改:
我将Linux内核升级到2.6.36.2(从2.6.26.2开始).内核升级后,测量时间变为60微秒,变化非常小,从升级前的75-100开始.为生产者和消费者线程设置CPU关联性没有任何影响,除非将它们限制在同一个核心.在同一核心上运行时,测得的延迟为13微秒.
在原始代码中,我让生产者在每次迭代之间进入休眠1秒钟,以便给消费者足够的时间来计算经过的时间并将其打印到控制台.如果我删除对Thread.sleep()的调用,而是让生产者和消费者在每次迭代中调用barrier.await()(消费者在将经过的时间打印到控制台后调用它),则测量的延迟从60微秒至10微秒以下.如果在同一核心上运行线程,则延迟低于1微秒.任何人都可以解释为什么这会显着减少延迟?我的第一个猜测是,这个改变产生了生成器在消费者调用queue.take()之前调用queue.put()的效果,所以消费者永远不必阻止,但在玩了一个修改版本的ArrayBlockingQueue后,我发现这个猜测是假的 - 消费者确实阻止了.如果您有其他猜测,请告诉我.(顺便说一句,如果我让生产者同时调用Thread.sleep()和barrier.await(),则延迟保持在60微秒).
我还尝试了另一种方法 - 而不是调用queue.take(),我调用了queue.poll(),超时为100微秒.这会将平均延迟降低到10微秒以下,但当然会占用更多的CPU(但繁忙等待的CPU密集程度可能更低).
再次编辑(1月10日) - 问题解决了:
ninjalj认为~60微秒的延迟是由于CPU不得不从更深的睡眠状态唤醒 - 而且他是完全正确的!在BIOS中禁用C状态后,延迟减少到<10微秒.这就解释了为什么我在上面的第2点获得了更好的延迟 - 当我更频繁地发送对象时,CPU保持足够忙,不能进入更深的睡眠状态.非常感谢所有花时间阅读我的问题并在此分享您的想法的人!
...
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CyclicBarrier;
public class QueueTest {
ArrayBlockingQueue<Long> queue = new ArrayBlockingQueue<Long>(10);
Thread consumerThread;
CyclicBarrier barrier = new CyclicBarrier(2);
static final int RUNS = 500000;
volatile int sleep = 1000;
public void start() {
consumerThread = new Thread(new Runnable() {
@Override
public …Run Code Online (Sandbox Code Playgroud) 我正在尝试用NodeJS创建一个多人游戏,我想在客户端之间同步动作.
在客户端和服务器之间找到延迟(请求返回客户端的时间)的最佳方法是什么?
我的第一个想法是客户端#1可以发送带有请求的时间戳,所以当客户端#2将接收客户端#1的动作时,他将调整动作速度以消除请求的延迟.但问题是,两个客户端的系统日期时间可能不相同,因此不可能两个人知道客户端#1请求的卷轴延迟.
另一个解决方案是使用服务器的时间戳,但现在我怎么知道客户端的延迟?
这是设置...您的系统正在接收包含离散消息的数据流(通常每条消息在32-128字节之间).作为处理管道的一部分,每条消息都通过两个物理上独立的应用程序,这些应用程序使用低延迟方法(例如UDP上的消息传递)或RDMA交换数据,最后通过相同的机制交换到客户端.
假设您可以在任何级别注入自己,包括线程协议分析,您将使用哪些工具和/或技术来衡量系统的延迟.作为其中的一部分,我假设传递给系统的每条消息都会导致相应的(虽然不是等效的)消息被推送到系统并传递给客户端.
我在市场上看到的唯一这样的工具是TS-Associates TipOff.我确信通过正确的访问,您可以使用线分析工具(ala wireshark)和正确的解剖器测量相同的信息,但这是正确的方法还是我可以使用任何商品解决方案?
我正在使用Python3 + bottle/UWSGI开发实时REST API.我的代码遇到了延迟,有时是100秒,这在我的应用程序中很重要.
使用logging模块,我试图识别代码的慢速部分,打印单个代码块运行的时间.我知道这是一种非常糟糕的分析代码的方法,但有时它能够很好地完成这项工作.
即使我发现了一些缓慢的部分,我仍然遗漏了一些东西 - 单个部分似乎需要10秒的ms,但通常它们整体上需要100秒.在一些越来越疯狂的实验让我几乎完全疯了之后,我得出以下结论:
t = round(100*time.time())
logging.info('[%s] Foo' % t)
logging.info('[%s] Bar' % t)
Run Code Online (Sandbox Code Playgroud)
令人惊讶的是,它给出了:
2014-07-16 23:21:23,531 [140554568353] Foo
2014-07-16 23:21:24,312 [140554568353] Bar
Run Code Online (Sandbox Code Playgroud)
虽然这似乎很难相信,但有两个后续logging.info()调用,并且由于某种原因,它们之间存在差不多800毫秒的差距.谁能告诉我发生了什么事?值得注意的是,如果有多个info()调用,则延迟仅在整个API方法中出现一次,最常见于其开始时(在第一次调用之后).我唯一的假设是磁盘延迟,有几个(但不是很多!)工作者同时运行,我正在使用旋转磁盘,没有SSD.但我认为有缓冲区,操作系统将为我异步执行磁盘刷新.我的假设错了吗?我应该避免完全记录以避免延迟吗?
编辑
根据Vinay Sajip的建议,我切换到以下初始化代码:
log_que = queue.Queue(-1)
queue_handler = logging.handlers.QueueHandler(log_que)
log_handler = logging.StreamHandler()
queue_listener = logging.handlers.QueueListener(log_que, log_handler)
queue_listener.start()
logging.basicConfig(level=logging.DEBUG, format="%(asctime)s %(message)s", handlers=[queue_handler])
Run Code Online (Sandbox Code Playgroud)
它似乎工作正常(如果我评论queue_listener.start(),没有输出),但仍然出现相同的延迟.我不知道怎么可能,呼叫应该是非阻塞的.我还在gc.collect()每个请求结束时确保问题不是由垃圾收集器引起的 - 没有任何影响.我也试图关闭整天的日志记录.延迟消失了,所以我认为他们的来源必须在logging模块中......
我正在将MS Access 2003应用程序升级为SQL Server后端.在我的开发机器上,SQL Server是本地的,因此性能非常好.我想用远程SQL Server测试性能,以便在重新设计应用程序时考虑网络延迟的影响.我期待一些现在看起来很快的查询在部署到生产后运行得相当慢.
如何在不使用虚拟机或将SQL重定位到另一台计算机的情况下减慢(或模拟远程)SQL Server的速度?是否有某种代理或Windows实用程序可以为我执行此操作?
这个问题有一个很长的版本,还有一个简短的版本.
简短版本:
为什么LINQ和EF在将单个大型(7 Mb)记录插入远程SQL Server数据库时这么慢?
这里是长版本 (包含一些有关变通方法的信息,可能对其他读者有用):
所有以下示例代码都运行正常,但由于我的用户位于欧洲,而我们的数据中心位于美国,因此速度很慢.但是,如果我在美国的Virtual PC上运行相同的代码,它会立即运行.(不,遗憾的是,我的公司希望将所有数据保留在内部,因此我无法使用Azure,Amazon Cloud Services等)
我的企业应用程序中有相当一部分涉及从Excel读取/写入数据到SQL Server,而且我们通常希望在SQL Server表中保存Excel文件的原始副本.
这非常简单,只需从本地文件中读取原始数据,然后将其保存到记录中即可.
private int SaveFileToSQLServer(string filename)
{
// Read in an Excel file, and store it in a SQL Server [External_File] record.
//
// Returns the ID of the [External_File] record which was added.
//
DateTime lastModifed = System.IO.File.GetLastWriteTime(filename);
byte[] fileData = File.ReadAllBytes(filename);
// Create a new SQL Server database record, containing our file's raw data
// (Note: the table has an IDENTITY Primary-Key, so …Run Code Online (Sandbox Code Playgroud) latency ×10
performance ×3
java ×2
networking ×2
sql-server ×2
bandwidth ×1
c# ×1
dns ×1
linq ×1
linux ×1
logging ×1
measurement ×1
ms-access ×1
node.js ×1
proxy ×1
python ×1
socket.io ×1
swing ×1
text ×1
throughput ×1
web ×1
websocket ×1