C/C++memcpu基准测试:测量CPU和墙时间

C/C++ memcpu benchmark: measuring CPU and wall time

本文关键字:CPU 时间 测量 C++memcpu 基准测试      更新时间:2023-10-16

一个基准测试怎么能memcpy?我写了测试代码,但它立即完成(可能是由于编译器优化(,并且实际上没有分配内存:

void test(void)
{
const uint32_t size = 4000'000'000;
char a[size], b[size];
printf("startn");
for(int i=0; i<10'000'000; i++)
memcpy(b, a, size*sizeof(char));
printf("endn");
}// end of function

我想知道memcpy在CPU时间和墙时间方面的成本

情况如下:我需要高速处理传入(通过网络(的数据。如果我处理得不够快,网络缓冲区就会被过度填充,我就会与数据源断开连接(这在我的测试代码中经常发生(。我可以看到我的进程的CPU使用率很低(10-15%(,因此应该有一些操作需要花费时间,而不需要花费CPU时间。因此,我想估计memcpy操作对处理一个单位数据所需的墙时间的贡献。代码基本上是一些计算和内存复制操作:没有资源,我需要等待,这可能会减慢我的速度。

谢谢你的帮助!

[编辑:]

非常感谢您的评论!很抱歉有一个不是C(仅限C++(的例子——我的首要任务是可读性。这里有一个新的代码示例,它表明memcpy不是免费的,并且消耗了100%的CPU时间:

const uint32_t N = 1000'000'000;
char *a = new char[N], 
*b = new char[N];
void test(void)
{
for(uint32_t i=0; i<N; i++)
a[i] = '7';
printf("startn");
for(int i=0; i<100; i++)
memcpy(b, a, N*sizeof(char));
printf("endn");
}// end of function

这让我很困惑为什么我的CPU使用率很低,但处理传入数据的速度不够快。

的想法是测试内存复制是否是通过在CPU参与较少的情况下直接复制RAM中的数据来完成的(这更有可能看到RAM块是否很大,因此过程不受CPU时间的支配(。

不,普通计算机上的memcpy不会卸载到DMA引擎/blitter芯片,并让CPU做其他事情,直到完成。CPU本身进行复制,因此就操作系统而言,memcpy与用户空间可能运行的任何其他指令没有什么不同。

嵌入式系统或Atari Mega ST上的C++实现似乎可以做到这一点,让操作系统安排另一项任务,或者至少做一些内务处理。尽管只有非常轻量级的上下文切换,因为复制甚至一大块内存都不需要很长时间。


找到答案的一种更简单的方法是单步执行memcpy库函数。(是的,在你的更新中,gcc并没有优化memcpy。(

除此之外,测试4GiB内存并不能很好地代表网络数据包。x86上的glibcmemcpy对非常大的拷贝使用不同的策略(NT存储(。例如,Linux内核的read/recv路径最终使用copy_to_user,我认为它使用了不同的内存复制功能:希望在具有ERMSB功能的x86 CPU上使用rep movsb

有关x86内存/缓存性能的详细信息,请参阅Enhanced REP MOVSB for memcpy。