5


我对文件 IO(C 语言)及其性能问题有疑问。

我有一个执行大量文件 I/O 的应用程序(在其生命周期内约 3-6 小时,大约 0.5-0.75TB,主要是文件输出)。目前,我的应用程序将sprintf()所有内容转换为 char 字符串,并在行write()s 的末尾转换为 file_descriptor。我的字符串长度为 1024 个字符,但可以在 64 到 1024 之间变化。无论如何。

问题是: 在执行
? 或者,假设缓冲由 处理,直接完全跳过文件是否更有意义?sprintf()write()sprintf()write()write()

我想到了一些东西,但不确定它是否真的会在性能方面完成任何事情:
如果我有一个结构来存储字符串、数字和字符串的各个部分,并改为执行结构的 mem_copy 怎么办?我猜类似于二进制写入?

我正在尝试实现“缓冲”方法或任何可以最大化性能的方法。后者是我需要使用该文件进行进一步处理。有什么建议么?

编辑
我做了一些简单的性能比较,printf(); + redirsprintf(); write();
只是将~20GB复制到一个文件中。

char string[1024];

for(i=0;i<(1<<20)*20;i++)
  printf("%s",string);

~/tmp/tests$ time ./printf.out > testing
real   2m22.101s
user   0m28.214s
sys    0m29.294s

相对于:

char string14[256]; ...etc
for(i=0;1<<(1<<20)*20;i++){
  sprintf(dst_string,"%s%s",dst_string, string14);
  sprintf(dst_string,"%s%s",dst_string, string24);
  sprintf(dst_string,"%s%s",dst_string, string34);
  sprintf(dst_string,"%s%s",dst_string, string44);
  write(fd, dst_string, 1024);
}

~/tmp/tests$ time ./write.out 

real   1m48.206s
user   0m58.544s
sys    0m41.079s

多个sprintf()s的原因是模拟copy->buffer然后写buffer。时间(无论如何都是真实的)并不像某些评论所暗示的那样微不足道。当然这是一个简单的例子,也许在计算 + IO 的方案中可能不会。

在 printf 示例中我有点困惑,额外的时间去哪儿了?用户+系统不加起来是真实的,他们至少不应该在球场上吗?因为缺少一个完整的 1:30m。

该测试是否显示任何结论?sprintf + write > 简单地打印+redir?

无论如何,谢谢大家的意见。

4

1 回答 1

6

当我在我的机器上进行一些测试时,我从不太现代的硬件中获得了大约 60MB/s 的速度。那是 3.6GB/分钟或每小时 216GB(所以 3 小时产生大约 640GB)。我希望在您的应用程序中花费的时间主要是“等待磁盘”,在这种情况下,您使用什么 IO 方法绝对没有区别。

但就像所有性能问题一样,这不是您可以通过在互联网上询问或在书中查找或其他任何方式找到的答案。它必须在您关注的系统上进行测量。将我的旧硬盘更换为一些配置良好的 RAID,你会获得更好的性能 [如果它是正确的 RAID 系统 - 有些比单个磁盘慢,因为目的不是加快访问速度,而是确保可靠性]。

您还可以进行一些比较: 1. 将软件的输出重定向到 /dev/null - 检查现在运行代码需要多长时间。如果它比您写入文件时快 10-100 倍,那么您知道您现在的写入方式或其他方法根本不会产生任何影响。2. 使用 (largenumber * 4KB = 典型文件大小) 创建类似大小的文件dd if=/dev/zero of=yourfile bs=4k count=largenumber- 如果您的应用程序正在写入多个文件,则编写一个脚本来写入多个类似的不同文件)。如果这比您的应用程序快得多,那么通过改变您从应用程序输出的方式可以获得一些好处。

如果上述两件事中的任何一件表明有可能获得收益,那么编写一些基准测试,以您希望应用程序工作的相同方式产生大量输出,看看有什么不同。一定要回来问问题。但我的猜测是,无论您对输出机制做什么,您的应用程序都不会运行得更快或更慢,因为这完全取决于“磁盘可以写入多快”。

于 2013-01-31T16:36:12.487 回答