我有两个程序,它们通过 Linux 管道(命名管道或非命名管道)相互传递数据。我需要在这两个程序之间实现大约 2600MB/s 的传输速率,但目前只能达到约 2200MB/s 的较慢速率。然而,我发现如果我用 'dd' 替换我的第二个进程,传输速率就能跳到 3000MB/s以上。是我的程序从管道中读取数据的方式不如 'dd' 高效吗?我该如何提高这种吞吐量?'ifstream' 读取二进制数据的方法是否天生比其他方法慢?
为了总结这两种情况:
场景1: Program1 -> [命名管道] -> Program2 产生约 2200MB/s 的传输速率。
场景2: Program1 -> [命名管道] -> 'dd if=pipename of=/dev/null bs=8M' 产生约 3000MB/s 的传输速率。
以下是我当前程序读取管道的方式:
为了总结这两种情况:
场景1: Program1 -> [命名管道] -> Program2 产生约 2200MB/s 的传输速率。
场景2: Program1 -> [命名管道] -> 'dd if=pipename of=/dev/null bs=8M' 产生约 3000MB/s 的传输速率。
以下是我当前程序读取管道的方式:
ifstream inputFile;
inputFile.open(inputFileName.c_str(), ios::in | ios::binary);
while (keepLooping)
{
inputFile.read(&buffer[0], 8*1024*1024);
bytesRead = inputFile.gcount();
//Do something with data
}
更新:
我现在尝试使用'read(fd, &buffer[0], 8*1024*1024)'代替istream,似乎显示了轻微的改善(但不如dd)。
我还尝试使用stream->rdbuf()->sgetn(&buffer[0], 8*1024*1024)代替stream->read(),但没有帮助。
dd
的源代码:http://lingrok.org/xref/coreutils/src/dd.c - jasonfstream
在处理区域设置时会有一些开销,但是dd
似乎使用了没有任何相关区域检查的read
。即使在ios::binary
模式下,你仍然需要支付一些这种惩罚。如果你使用FILE*
,你的性能会如何变化?虽然它不像C++那样优雅,但如果性能是你关心的问题... - Dan Lecocq