如何进行基准测试?我编写了测试代码,但是它立即完成(可能是由于编译器的优化),并且实际上并没有分配内存:
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使用率较低,但是处理输入数据的速度不够快。
答案 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。