4

我正在设计一个偶尔需要复制大量内存的实时系统。内存由非微小区域组成,因此我预计复制性能将相当接近相关组件(CPU、RAM、MB)可以执行的最大带宽。这让我想知道现代商品机器可以召集什么样的原始内存带宽?

如果我使用 1 个线程,我老化的 Core2Duo 给我 1.5 GB/s memcpy()(如果我同时使用两个内核,可以理解更少memcpy()。)虽然 1.5 GB 是相当多的数据,但我正在处理的实时应用程序将有大约是 1/50 秒,这意味着 30 MB。基本上,几乎没有。也许最糟糕的是,当我添加多个内核时,我可以处理更多数据,而无需为所需的复制步骤增加任何性能。

但如今,低端 Core2Due 并不是很热门的东西。是否有任何网站提供有关当前和近期硬件上的原始内存带宽的信息,例如实际基准测试?

此外,对于在内存中复制大量数据,是否有任何捷径,或者memcpy()尽可能好?

鉴于一堆核心无事可做,只能在短时间内复制尽可能多的内存,我能做的最好的事情是什么?

编辑:我仍在寻找有关原始内存复制性能的良好信息。我刚刚运行了我的旧memcpy()基准。相同的机器和设置,现在提供 2.5 GB/s...

4

2 回答 2

2

在 Nehalem 等较新的 CPU 上,以及自 Opteron 以来的 AMD 上,内存对于一个 CPU 来说是“本地的”,其中一个 CPU 可能有多个内核。也就是说,内核访问连接到其 CPU 的本地内存需要一定的时间,而内核访问远程内存需要更多时间,其中远程内存是其他 CPU 本地的内存。这称为非统一内存访问,或 NUMA。为获得最佳 memcpy 性能,您希望将 BIOS 设置为 NUMA 模式,将线程固定到内核,并始终访问本地内存。在 wikipedia 上了解有关NUMA 的更多信息。

不幸的是,我不知道有关最近 CPU 和芯片组上 memcpy 性能的网站或最近的论文。您最好的选择可能是自己测试它。

至于memcpy()性能,有很大的差异,具体取决于实现。例如,英特尔 C 库(或者可能是编译器本身)的memcpy()速度比 Visual Studio 2005 提供的快得多。至少在英特尔机器上。

你能做的最好的内存拷贝将取决于你的数据的对齐方式,你是否能够使用向量指令,以及页面大小等。实现一个好的memcpy()是令人惊讶的,所以我建议找到并测试尽可能多的实现尽可能在自己编写之前。如果您了解有关您的副本的更多细节,例如对齐方式和大小,您可能能够比 Intel 的memcpy(). 如果您想了解详细信息,可以从 Intel 和 AMD 优化指南或Agner Fog 的软件优化页面开始。

于 2010-03-18T01:50:01.350 回答
1

我认为您以错误的方式处理问题。我认为,目标是在不破坏实时性能的情况下导出一致的数据快照。不要使用硬件,使用算法。

您要做的是在数据之上定义一个日志系统。当你开始你的内存传输时,你有两个线程:一个可以工作并认为它正在修改数据的原始线程(但实际上只是写入日志),一个新线程将旧的(未记录的)数据复制到一个单独的地方,这样它就可以慢慢写出来。

新线程完成后,您将其用于将数据集与日志合并,直到日志为空。完成后,旧线程可以返回直接与数据交互,而不是通过日志修改版本进行读取/写入。

最后,新线程可以转到复制的数据并开始慢慢地将其传递给远程源。

如果您设置这样的系统,您可以在运行的系统中获得任意大量数据的即时快照,只要您可以在日志变得如此满以至于实时系统可以之前完成内存中的复制跟不上它的处理需求。

于 2010-03-18T22:42:50.883 回答