C/C++ memcpu 基准测试:测量 CPU 和 wall time
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("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 使用率很低,但处理传入数据的速度不够快。
the idea was to test if memory copy is done by directly copying data in RAM with small participation of CPU (which is more likely to see if RAM chunks are large, and so the process is not dominated by CPU time).
不,memcpy
在普通计算机上不会卸载到 DMA 引擎/blitter chip 并让 CPU 做其他事情直到完成。 CPU 本身进行复制,因此就 OS 而言,memcpy 与任何其他指令没有区别 user-space 可能是 运行.
嵌入式系统上的 C++ 实现或 Atari Mega ST 可以合理地做到这一点,让 OS 安排另一项任务或至少做一些内务处理。尽管只有非常轻量级的上下文切换,因为它根本不需要很长时间来复制一个巨大的内存块。
更简单的方法是单步执行 memcpy
库函数。 (是的,随着你的更新,gcc 并没有优化掉 memcpy
。)
除此之外,测试 4GiB memcpy 对网络数据包来说不是很具有代表性。 x86 上的 glibc memcpy
对非常大的副本使用不同的策略(NT 存储)。例如,我假设 Linux 内核的 read
/ recv
路径最终使用 copy_to_user
,它使用不同的内存复制功能:希望 rep movsb
x86 CPUs 具有 ERMSB 功能。
有关 x86 内存/高速缓存性能的详细信息,请参阅 。
一个基准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 使用率很低,但处理传入数据的速度不够快。
the idea was to test if memory copy is done by directly copying data in RAM with small participation of CPU (which is more likely to see if RAM chunks are large, and so the process is not dominated by CPU time).
不,memcpy
在普通计算机上不会卸载到 DMA 引擎/blitter chip 并让 CPU 做其他事情直到完成。 CPU 本身进行复制,因此就 OS 而言,memcpy 与任何其他指令没有区别 user-space 可能是 运行.
嵌入式系统上的 C++ 实现或 Atari Mega ST 可以合理地做到这一点,让 OS 安排另一项任务或至少做一些内务处理。尽管只有非常轻量级的上下文切换,因为它根本不需要很长时间来复制一个巨大的内存块。
更简单的方法是单步执行 memcpy
库函数。 (是的,随着你的更新,gcc 并没有优化掉 memcpy
。)
除此之外,测试 4GiB memcpy 对网络数据包来说不是很具有代表性。 x86 上的 glibc memcpy
对非常大的副本使用不同的策略(NT 存储)。例如,我假设 Linux 内核的 read
/ recv
路径最终使用 copy_to_user
,它使用不同的内存复制功能:希望 rep movsb
x86 CPUs 具有 ERMSB 功能。
有关 x86 内存/高速缓存性能的详细信息,请参阅