【问题标题】:Which bottleneck is hit using printf on > 65KB strings?在大于 65KB 的字符串上使用 printf 会遇到哪个瓶颈?
【发布时间】:2012-08-07 19:01:02
【问题描述】:

这个程序每行打印 65k 字节。

我用./a.out | pv >/dev/null 测量吞吐量,得到大约 3 GB/s。

只要我将线路长度更改为 70k,吞吐量就会下降到 ~ 1 GB/s。

哪个瓶颈(CPU 缓存、libc 特质等)我遇到了什么问题?

#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);
}

更新:我在 Ubuntu 12.04 64 位上运行它,它有 EGLIBC 2.15,在 Core i5-2520M 上。

更新:puts (s) 也有同样的问题。

【问题讨论】:

  • 同样重要——你使用的是什么 libc,什么版本?
  • 可能是 libc 的内部缓冲区,尤其是在 printf 内部。 puts 怎么样?
  • 我不确定这是否是有用的信息,但65000 适合两个字节,而70000 需要三个。对于比我知识渊博的人来说,这可能是一个起点?
  • 你需要在profiler下运行你的程序来回答这个问题。
  • 瓶颈在你的a.out,还是在pv?

标签: c performance caching printf benchmarking


【解决方案1】:

您在数据传输中未充分利用内核 I/O 缓冲区。如果我们假设 64KB 是内核 I/O 缓冲区大小,那么 70000 写入将在写入 64KB 后阻塞。当它耗尽时,剩余的 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] [    <=>                                            ]

编辑:再运行三个(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] [          <=>                                      ]

【讨论】:

  • 块大小的差异在我的机器上似乎可以忽略不计。
  • 我试过 30k、80k 和 500k。都在 15% 以内。不过,代码中的 6500070000 会产生 2 倍的差异。
  • @Mysticial:更大不会改善。尝试 4k、8k 和 16k。
  • @nh2 每个核心实际上只有 32k。但是你是对的,这两个测试用例都非常适合 L2 缓存。
  • @nh2 这里还有一些数字可以看:pastebin.com/WyEeN5Lp 除了 200k 块大小之外,基本上没有区别。 (编辑:更新链接更详细)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-17
  • 2012-11-08
  • 2020-11-15
  • 2011-05-25
  • 2021-07-24
  • 2012-10-31
  • 2012-12-03
相关资源
最近更新 更多