问题标签 [latency]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 为什么一个循环比另一个循环检测共享内存更新需要更长的时间?
我编写了一个写入共享内存的“服务器”程序,以及一个从内存中读取的客户端程序。服务器有不同的“通道”可以写入,它们只是不同的链接列表,它也可以附加项目。客户端对某些链表感兴趣,并希望读取添加到这些链表中的每个节点,并尽可能降低延迟。
我有两种方法供客户使用:
对于每个链表,客户端保留一个“书签”指针以保持其在链表中的位置。它循环循环链表,一遍又一遍地遍历所有链表(它永远循环),如果可以的话,每次将每个书签向前移动一个节点。是否可以由节点的“下一个”成员的值确定。如果它是非空的,那么跳转到下一个节点是安全的(服务器自动将它从空切换到非空)。这种方法工作正常,但是如果有很多列表要迭代,并且只有少数列表正在接收更新,那么延迟就会变差。
服务器给每个列表一个唯一的 ID。每次服务器将项目附加到列表时,它也会将列表的 ID 号附加到主“更新列表”。客户端只保留一个书签,一个书签到更新列表中。它无休止地检查书签的下一个指针是否为非空(
while(node->next_ == NULL) {}
),如果是,则继续读取给定的 ID,然后处理链表上具有该 ID 的新节点。从理论上讲,这应该可以更好地处理大量列表,因为客户端不必每次都遍历所有列表。
当我对这两种方法的延迟进行基准测试时(使用 gettimeofday),令我惊讶的是#2 非常糟糕。对于少量链表,第一种方法的延迟通常低于 20us。第二种方法会有少量低延迟,但通常在 4,000-7,000us 之间!
通过在这里和那里插入 gettimeofday,我确定方法 #2 中所有增加的延迟都花在循环中,反复检查下一个指针是否为非空。这让我很困惑;就好像一个流程中的更改需要更长的时间才能使用第二种方法“发布”到第二个流程。我假设正在进行某种我不明白的缓存交互。这是怎么回事?
更新:最初,方法 #2 使用条件变量,因此如果node->next_ == NULL
它会等待条件,服务器会在每次发布更新时通知该条件。延迟是相同的,并且试图弄清楚为什么我将代码减少到上述方法。我在多核机器上运行,所以一个进程自旋锁不应该影响另一个。
更新 2: node->next_ 是不稳定的。
mutex - 测量互斥体或 futex 延迟
如何测量互斥量、信号量或 futex 的延迟?我的意思是两个事件之间的延迟:解锁先前锁定的互斥锁和锁定该互斥锁。有两种情况:当所有线程/进程都在同一个 CPU 上时(重新调度线程需要多长时间)以及当第一个线程在第一个 CPU 上而第二个线程在第二个 CPU 上时。
甚至
这个时间很短(~1 k 个周期),所以我不能使用gettimeofday()
python - 测量服务器的 ping 延迟 - Python
我有一个服务器IP 地址列表,我需要检查每个地址是否在线以及延迟多长时间。
我还没有找到任何直接的方法来实现这一点,而且在准确计算延迟方面似乎存在一些问题。
有任何想法吗?
c++ - 在这 3 种从共享内存中读取链表的方法中,为什么第三快?
我有一个“服务器”程序,可以更新共享内存中的许多链接列表以响应外部事件。我希望客户端程序尽快注意到任何列表的更新(最低延迟)。服务器将链表的节点标记state_
为FILLED
一旦其数据被填充并且其下一个指针已设置为有效位置。在那之前,它state_
是NOT_FILLED_YET
。我正在使用内存屏障来确保客户端不会state_
像FILLED
以前一样看到其中的数据实际上已经准备好(而且它似乎有效,我从来没有看到损坏的数据)。此外,state_
它是不稳定的,以确保编译器不会将客户端的检查从循环中解除。
保持服务器代码完全相同,我为客户端提供了 3 种不同的方法来扫描链接列表以进行更改。问题是:为什么第三种方法最快?
方法 1:连续循环遍历所有链表(称为“通道”),查看是否有任何节点已更改为“已填充”:
当通道数量很少时,方法 1 的延迟非常低。但是当频道数量增加(250K+)时,由于循环遍历所有频道,它变得非常慢。于是我试了...
方法二:给每个链表一个ID。在旁边保留一个单独的“更新列表”。每次更新链表之一时,将其 ID 推送到更新列表。现在我们只需要监控单个更新列表,并检查我们从中获得的 ID。
方法 2 给出了可怕的延迟。方法 1 可能会给出低于 10 毫秒的延迟,而方法 2 会莫名其妙地经常给出 8 毫秒的延迟!使用 gettimeofday 似乎 update_cursor->state_ 的变化从服务器的视图传播到客户端的视图非常缓慢(我在一个多核机器上,所以我认为延迟是由于缓存造成的)。所以我尝试了一种混合方法......
方法三:保留更新列表。但是不断循环遍历所有通道,并在每次迭代中检查更新列表是否已更新。如果有,请使用推到其上的号码。如果没有,请检查我们当前迭代到的通道。
此方法的延迟与方法 1 一样好,但可以扩展到大量通道。问题是,我不知道为什么。只是为了解决问题:如果我取消注释“通过更新找到”部分,它会在每个延迟日志消息之间打印。这意味着东西只能在更新列表中找到!所以我不明白这种方法如何比方法2更快。
生成随机字符串作为测试数据的完整可编译代码(需要 GCC 和 boost-1.41)位于: http: //pastebin.com/0kuzm3Uf
更新:所有 3 种方法都有效地自旋锁定,直到发生更新。不同之处在于他们注意到更新发生需要多长时间。它们都不断地对处理器征税,因此这并不能解释速度差异。我正在一台 4 核机器上进行测试,没有其他任何东西在运行,所以服务器和客户端没有什么可竞争的。我什至制作了一个代码版本,其中更新表示条件并让客户端等待条件 - 它无助于任何方法的延迟。
Update2:尽管有 3 种方法,但我一次只尝试了 1 种,因此只有 1 个服务器和 1 个客户端在竞争 state_ 成员。
.net - 使用 .NET 在慢速网络中移动不同大小文件的最佳方式
我正在构建一个 .NET 远程客户端/服务器,它将传输数千个不同大小的文件(从几个字节到数百 MB 不等),我想要一些关于实现此目标的最佳方法的反馈。在我看来,有几个选择:
- 将整个文件序列化到我的远程处理对象中并一次传输,无论大小。这可能是最快的,但是传输过程中的失败需要重新传输整个文件,无法恢复。
- 如果文件大小大于小文件(如 4KB),请将其分成 4KB 的块并远程处理,在服务器上重新组装。除了复杂性之外,由于持续的往返和确认,它更慢,尽管任何一个部分的失败都不会浪费太多时间。
- 在我的应用程序中包含 FTP 或 SFTP 服务器之类的东西 - 客户端将通知服务器它开始使用远程处理,上传文件,然后使用远程处理来通知完成。我想在我的应用程序中包含所有内容,而不是需要单独的 FTP 服务,但如果需要,我愿意接受这个选项。
- 使用某种声明的 TCP 连接或 WPF 或其他为处理故障或能够执行某种检查点/恢复而构建的传输方法。
- 还有其他我想念的吗?
最灵活/可靠的传输方式是什么?我不太关心速度,但更关心可靠性 - 我希望文件移动,即使它很慢。由于客户端和服务器将是多线程的,如果连接允许,我可以同时传输多个文件。
感谢您的反馈 - 我将提供赏金以获得有关人们实现此目标的方法的一些建议。
java - Java 和 C/C++ 之间进程间通信的最快(低延迟)方法
我有一个 Java 应用程序,通过 TCP 套接字连接到用 C/C++ 开发的“服务器”。
应用程序和服务器都在同一台机器上运行,一个 Solaris 机器(但我们正在考虑最终迁移到 Linux)。交换的数据类型是简单的消息(登录、登录 ACK、然后客户端请求某些内容、服务器回复)。每条消息大约 300 字节长。
目前我们正在使用套接字,一切都很好,但是我正在寻找一种更快的方式来交换数据(更低的延迟),使用 IPC 方法。
我一直在研究网络并提出了对以下技术的参考:
- 共享内存
- 管道
- 排队
- 以及所谓的 DMA(直接内存访问)
但是我找不到对它们各自性能的正确分析,也找不到如何在 JAVA 和 C/C++ 中实现它们(以便它们可以相互交谈),除了我可以想象如何做的管道。
在这种情况下,任何人都可以评论每种方法的性能和可行性吗?任何指向有用实现信息的指针/链接?
编辑/更新
在我在这里得到的评论和答案之后,我找到了有关 Unix Domain Sockets 的信息,它似乎是在管道上构建的,并且可以为我节省整个 TCP 堆栈。它是特定于平台的,因此我计划使用 JNI 或juds或junixsocket 对其进行测试。
下一个可能的步骤是直接实现管道,然后是共享内存,尽管我已经被警告过额外的复杂性......
感谢您的帮助
iphone - 大 iPhone Ping 时间是否表明应用程序延迟?
我正在考虑创建一个实时应用程序,其中 iPod Touch/iPhone/iPad 与服务器端组件(产生 MIDI,并在主机内向前发送)对话。当我在 Wifi 上 ping 我的 iPod Touch 时,我得到了巨大的延迟(以及巨大的差异):
即使这是 iPhone->Host 或 Host->iPhone 时间的两倍,对于我正在考虑的应用程序来说,15ms+ 也太长了。有没有更快的方法解决这个问题(例如,USB 电缆)?如果没有,在 Android 上构建应用程序会提供任何其他选择吗?
Traceroute 报告更多可行时间:
任何人都可以为我解读 ping 和 traceroute 之间的这种区别,以及它们对于需要与主机通信(和从主机通信)的应用程序可能意味着什么?
performance - linux中收发tcp/udp数据包延迟的来源
在 linux 2.6 中发送/接收 TCP/UDP 数据包的过程中延迟的来源是什么?
我想知道“乒乓”延迟测试中的延迟源。
有一些关于以太网延迟的相当不错的论文,但它们仅涵盖了线路和交换机中的延迟源(并且相当粗略,仅针对特定交换机)。
数据包之后有哪些处理步骤?
对常用 ping (icmp) 进行深度延迟分析的论文也会很有用。
我依赖社区:)
networking - 从“写”系统调用到 I/O 寄存器编程的 tcp 数据的数据路径(行程)
是否对 Linux 中的 tcp 数据路径有一个很好的概述(2.6,如果路径实际上不同,则不是 2.4)?tcp/ip 堆栈处理不同阶段的数据包在哪里?
数据包如何打包到 tcp 段,然后是 ip 数据包。它是如何传输到网卡的?(使用一系列 I/O 寄存器写入和 DMA?)它是在“写入”系统调用处理程序(带有一些深度调用堆栈)中传输到网卡还是在其他时刻传输?
performance - 一个双向 tcp 套接字还是两个单向?(Linux,大容量,低延迟)
我需要在两台机器之间以尽可能低的延迟定期发送(交换)大量数据。网络相当快(例如 1Gbit 甚至 2G+)。操作系统是linux。使用 1 个 tcp 套接字(用于发送和接收)还是使用 2 个单向 tcp 套接字会更快吗?
此任务的测试非常类似于 NetPIPE 网络基准测试 - 测量从 2^1 到 2^13 字节大小的延迟和带宽,每个大小发送和接收至少 3 次(在青色任务中,发送次数更多。两者进程将发送和接收,就像乒乓球一样)。
2个单向连接的好处来自linux:
http://lxr.linux.no/linux+v2.6.18/net/ipv4/tcp_input.c#L3847
禁用快速路径的所有其他条件都是错误的。并且只有非单向套接字会阻止内核从快速路径接收