gpt4 book ai didi

c++ - 为什么 'dd' 从管道读取的速度比我自己使用 ifstream 的程序更快?

转载 作者:IT王子 更新时间:2023-10-29 00:21:52 29 4
gpt4 key购买 nike

我有两个程序通过 linux 管道(命名或其他方式)相互传递数据。我需要在两个程序之间达到 ~2600 MB/s 的传输速率,但目前看到的传输速率较慢,约为 ~2200 MB/s。但是,我发现如果我将第二个进程替换为“dd”,传输速率会跃升至超过 3000 MB/s。我的程序从管道读取的方式是否比“dd”的方式效率低?我可以做些什么来提高这个吞吐量? “ifstream”本质上比其他从管道读取二进制数据的方法慢吗?

总结这两种情况:

Scenario 1:

Program 1 -> [named pipe] -> Program 2

Yields ~2200 MB/s transfer rate

Scenario2:

Program 1 -> [named pipe] -> 'dd if=pipename of=/dev/null bs=8M'

Yields ~3000 MB/s transfer rate.

这是我的程序 2 当前从管道读取的方式:

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(),但没有帮助。

最佳答案

差异似乎是由于使用数组而不是 std::vector,我仍然很难相信这一点。我的两组代码如下所示,以供比较。第一个可以以大约 2500 MB/s 的速度从程序 1 中摄取。第二个可以以 3100 MB/s 的速率摄取。

程序 1(2500 MB/秒)

int main(int argc, char **argv)
{
int fd = open("/tmp/fifo2", O_RDONLY);

std::vector<char> buf(8*1024*1024);

while(1)
{
read(fd, &buf[0], 8*1024*1024);
}
}

程序 2(3100 MB/秒)

int main(int argc, char **argv)
{

int fd = open("/tmp/fifo2", O_RDONLY);

char buf[8*1024*1024];

while(1)
{
read(fd, &buf[0], 8*1024*1024);
}
}

两者都是使用 gcc 版本 4.4.6 以 -O3 编译的。如果有人能解释其中的原因,我会非常感兴趣(因为我理解 std::vector 基本上是数组的包装器)。

编辑:我刚刚测试了下面的程序 3,它可以使用 ifstream 并以 3000 MB/s 的速度运行。因此,似乎使用 ifstream 而不是“read()”会导致非常轻微的性能下降。远低于使用 std::vector 的命中率。

程序 3(3000 MB/s)

int main(int argc, char **argv)
{
ifstream file("/tmp/fifo2", ios::in | ios::binary);

char buf[8*1024*1024];

while(1)
{
file.read(&buf[0], 32*1024);
}
}

编辑 2:

我修改了程序 2 的代码以使用 malloc 内存而不是堆栈上的内存,性能下降以匹配 vector 性能。感谢 ipc,让我了解这一点。

关于c++ - 为什么 'dd' 从管道读取的速度比我自己使用 ifstream 的程序更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15666460/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com