C/C++memcpu基准测试:测量CPU和墙时间
C/C++ memcpu benchmark: measuring CPU and wall time
一个基准测试怎么能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。
- 分别测量每个线程上花费的 CPU 时间(C++)
- 超过CPU时间限制:当MPI_Sent一个非常大的int*时
- 如何测量一组特定线程的 CPU 时间?
- 如何以C++而不是 CPU 时间测量挂钟时间
- 将返回 CPU 时间提升为 0
- C++中的双感叹号(!!)会花费更多的CPU时间吗
- 即使使用睡眠,线程也不会放弃CPU时间
- 以C++为单位测量程序的 CPU 时间和挂钟时间
- 在 Windows 上以C++计算 CPU 时间
- 时间短函数与 CPU 时间使用 RTEMS 操作系统
- PDH 无法通过 PdhAddCounter() 访问总 CPU 时间
- 二叉搜索真的是在 0 时钟 CPU 时间内执行的吗?
- 我应该检查什么:cpu时间还是墙时间
- 使用MPI时计算CPU时间
- 堆排序CPU时间
- rusage的进程/线程的Cpu时间不可能
- 如何在 Windows 上以 C++ 为单位测量 CPU 时间并包括 system() 的调用
- 在 Ubuntu 中获取 CPU 时间
- 为什么使用 clock() 在测量 CPU 时间时得到减号
- 使用 GetProcessTimes 测量 Windows 上的 CPU 时间