C++ 在最坏的情况下,QPI延迟能使任意应用程序减慢多少?

C++ 在最坏的情况下,QPI延迟能使任意应用程序减慢多少?,c++,performance,latency,low-latency,C++,Performance,Latency,Low Latency,我正在开发低延迟HFT交易应用程序 我用的是单CPU机器。因为它更易于配置和维护(无需调优NUMA)。另外,显然,假设我们有足够的资源,它肯定不会比双CPU设置慢,而且可能会快一点,不会导致QPI/NUMA延迟 HFT需要大量的资源,现在我意识到我想要更多的内核。同时,将两台1U单CPU计算机合并比将一台1U双CPU计算机合并要昂贵得多,因此即使假设我可以将程序“拆分”为两台,使用1U双CPU计算机仍然是有意义的 那么QPI/NUMA延迟有多大?如果我将我的应用程序从单CPU机器移动到双CPU机

我正在开发低延迟HFT交易应用程序

我用的是单CPU机器。因为它更易于配置和维护(无需调优NUMA)。另外,显然,假设我们有足够的资源,它肯定不会比双CPU设置慢,而且可能会快一点,不会导致QPI/NUMA延迟

HFT需要大量的资源,现在我意识到我想要更多的内核。同时,将两台1U单CPU计算机合并比将一台1U双CPU计算机合并要昂贵得多,因此即使假设我可以将程序“拆分”为两台,使用1U双CPU计算机仍然是有意义的

那么QPI/NUMA延迟有多大?如果我将我的应用程序从单CPU机器移动到双CPU机器,它会慢多少?我最多可以承受几微秒的延迟,但不能超过。如果没有正确调谐,QPI/Numa会引入显著延迟吗?该延迟的显著程度如何


是否有可能编写这样的应用程序,它在双CPU设置上的运行速度比单CPU设置慢得多(慢几微秒以上)?也就是说,在速度更快的计算机上运行速度要慢得多?(当然,假设我们有相同的处理器、内存、网卡和其他一切)

这不是一个简单的问题,因为它取决于许多因素。代码是为NUMA编写的吗

代码主要执行读取、写入还是大致相同?在独立CPU上运行的线程之间共享多少数据?强制缓存刷新时,此类数据写入的频率是多少

如何安排任务,操作系统如何以及何时决定将线程从一个CPU插槽移动到下一个CPU插槽

代码和数据是否适合缓存

这些只是几个因素,它们将在“工作非常好”和“性能非常差”之间显著改变结果

与所有与性能相关的问题一样,细节可能会产生巨大的影响,在互联网上阅读这样的答案不会给你一个适用于你的情况的可靠答案。对应用程序进行基准测试,检查性能计数器,并基于此进行调整。[考虑到您在上述评论中描述的规格机器的价格,我希望供应商会允许某种测试、演示、“购买前试用”等]

假设您有一个最坏的情况,内存访问将跨越两条缓存线(例如,8字节值的未对齐访问),这两条缓存线被分割在最坏的CPU之间,MMU需要重新加载,这些页表条目中的每一个都位于最坏的CPU中,由于这对内存位置的内存位于不同的位置,因此需要为两个4字节读取中的每一个读取新的TLB条目来加载64位值。(每个TLB入口是一个单独的位置)

这意味着2 x 4 x n,其中n类似于。因此,一次内存访问至少在理论上需要1600纳秒。所以1.6微秒。你不太可能因为一次手术而变得比这更糟。这种开销比交换到磁盘的开销要小得多,因为交换到磁盘会增加毫秒的执行时间

编写在多个CPU上更新同一缓存线的代码并不难,从而导致性能的大幅降低——我记得很久以前,我第一次使用Athlon SMP系统运行简单的基准测试时,作者为Dhrystone基准测试这么做

int numberOfRuns[MAX_CPUS];
现在,
numberOfRuns
是外部循环计数器,在任一CPU上更新每个循环的计数器都会导致“错误共享”(因此每次更新计数器时,另一个CPU都必须刷新该缓存线)

在2核SMP系统上运行它可以提供30%的单CPU性能。因此比单CPU慢3倍,而不是像您预期的那样快。(这是大约12年前的事了,所以内存在细节上可能有点“关闭”,但这个故事的本质仍然是正确的——写得不好的应用程序在多核上的运行速度可能比单核慢)

我认为,在一个现代系统中,通常使用的变量的错误共享至少会导致糟糕的性能

相比之下,如果CPU内核之间几乎没有共享,那么编写良好的代码应该运行快近N倍。我有一个高度受CPU限制的多线程计算器,在家里的单插槽系统和工作中的双插槽系统上,它的性能提高了近n倍

$ time ./weird -t 1 -e 100000

real    0m22.641s
user    0m22.660s
sys 0m0.003s

$ time ./weird -t 6 -e 100000

real    0m5.096s
user    0m25.333s
sys 0m0.005s

所以大约11%的开销。这是共享一个变量[当前数字],它在线程之间原子化(使用C++标准原子)。不幸的是,我没有一个“写得很糟糕的代码”的好例子来与之对比。

我认为这个问题太模糊了。你期望得到什么样的答案?“QPI将增加12微秒的延迟”,或者类似的东西?对于当时的“任意应用程序”。使用NUMA时,必须小心不要访问分配给不同内核的内存。如果这样做,两个内核都会受到延迟。(对不起,我没有这方面的数字。但它应该是可量化的,所以这可能是你的问题。)但避免这个问题不是火箭科学。我同意尊敬的@DanielDarabos,你的观点。我似乎记得,寻址邻居ram会额外花费你大约100个周期或25纳秒。你需要使用。而且,你的很多推理都是不正确的。例如,更多的物理CPU意味着更多的缓存,这对延迟有巨大的影响。我同意这个问题是模糊的。我希望有人能解释为什么QPI会减慢应用程序的速度,以及QPI如何减慢应用程序的速度,最糟糕的情况是什么,恐惧是什么。例如,QPI是否有可能在某个时刻开始将几GB的RAM从一个NUMA节点移动到另一个NUMA节点,这会带来巨大的延迟,比如说100微秒或类似的延迟?@DavidSchwartz我熟悉这种硬件。现在我用的是普通的硬件。您认为这款双插座E5-2687 v3会更快吗