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

标签 c++ linux pipe ifstream

我有两个程序通过 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/

相关文章:

c++ - 如何使用 Python C/API 包装多线程 C++ 库?

c++ - 不会匹配模板函数

linux - 如何从 Linux ls 或 find 命令的文件列表中获取内容

batch-file - 如何使用批处理脚本将未清理的字符串复制到剪贴板

c++ - 如何知道何时在 C++ 中调用 delete 以及何时调用 delete[]?

c++ - 以秒为单位获取 boost::posix_time::time_duration

linux - BASH - 删除行并用空行替换它们

linux - 从用户空间访问 ARM PLE(预加载引擎)(或如何获得全带宽内存访问)

使用子命令和 R 中的管道运算符方法删除特定列中的字符

c# - 为什么 ffmpeg 在进程中随机停止?