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

时间:2019-11-08 21:10:14

标签: c++ c benchmarking memcpy

如何进行基准测试?我编写了测试代码,但是它立即完成(可能是由于编译器的优化),并且实际上并没有分配内存:

void test(void)
{
 const uint32_t size = 4000'000'000;
 char a[size], b[size];
 printf("start\n");
 for(int i=0; i<10'000'000; i++)
     memcpy(b, a, size*sizeof(char));
 printf("end\n");
}// 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("start\n");
 for(int i=0; i<100; i++)
     memcpy(b, a, N*sizeof(char));
 printf("end\n");
}// end of function

这让我感到困惑,为什么我的CPU使用率较低,但是处理输入数据的速度不够快。

1 个答案:

答案 0 :(得分:1)

  

这个想法是要测试是否通过在CPU参与较少的情况下直接复制RAM中的数据来完成内存复制(这很可能会发现RAM块是否很大,因此该过程不受CPU时间的支配)。 / p>

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

嵌入式系统或Atari Mega ST上的C ++实现可以合理地做到这一点,让OS安排其他任务或至少进行一些内部管理。尽管仅使用非常轻量级的上下文切换,因为复制甚至不需要很大的内存块都不需要花费很长时间。


一种更容易发现的方法是单步进入memcpy库函数。 (是的,对于您的更新,gcc并不能优化memcpy。)

除此之外,测试4GiB memcpy对于网络数据包不是很有代表性。 x86上的glibc memcpy对巨大的副本使用不同的策略(NT存储)。例如,我假设Linux内核的read / recv路径最终使用copy_to_user,它使用了不同的内存复制功能:希望rep movsb在x86 CPU上具有ERMSB功能。

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