nh2*_*nh2 11 c performance benchmarking printf caching
该程序每行打印65k字节.
我测量吞吐量./a.out | pv >/dev/null并达到3 GB/s左右.
一旦我将线路长度更改为70k,吞吐量就会下降到~1 GB/s.
我在这里遇到了哪个瓶颈(CPU缓存,libc idiosynchrasy等)?
#include <stdio.h>
#include <string.h>
#define LEN 65000 // high throughput
// #define LEN 70000 // low throughput
int main ()
{
char s[LEN]; memset(s, 'a', LEN-1); s[LEN-1] = '\0';
while (1)
printf ("%s\n", s);
}
Run Code Online (Sandbox Code Playgroud)
更新:我在Core i5-2520M上运行64位Ubuntu 12.04,它有EGLIBC 2.15.
更新: puts (s)有同样的问题.
您正在使用数据传输中的内核I/O缓冲区.如果我们假设64KB是内核I/O缓冲区大小,那么在写入64KB之后将会阻塞70000写入.当它耗尽时,剩余的4KB +更改被写入I/O缓冲区.pv最终执行两次读取以读取每个70000传输的字节,由于缓冲区利用率不佳导致正常吞吐量的一半左右.写入期间I/O中的停顿可能构成其余部分.
您可以指定较小的读取大小pv,这将通过增加每个时间片传输的平均字节数来提高吞吐量.写入将平均更高效,并保持读取缓冲区满.
$ ./a.out | pv -B 70000 > /dev/null
9.25GB 0:00:09 [1.01GB/s] [ <=> ]
$ ./a.out | pv -B 30k > /dev/null
9.01GB 0:00:05 [1.83GB/s] [ <=> ]
Run Code Online (Sandbox Code Playgroud)
编辑:三次运行(2.7GHz核心i7)
$ ./a.out | pv -B 16k > /dev/null
15GB 0:00:08 [1.95GB/s] [ <=> ]
$ ./a.out | pv -B 16k > /dev/null
9.3GB 0:00:05 [1.85GB/s] [ <=> ]
$ ./a.out | pv -B 16k > /dev/null
19.2GB 0:00:11 [1.82GB/s] [ <=> ]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
303 次 |
| 最近记录: |