简体   繁体   English

为什么使用ddstream从管道中读取“ dd”要比我自己的程序快?

[英]Why can 'dd' read from a pipe faster than my own program using ifstream?

I have two programs that pass data to each other via linux pipes (named or otherwise). 我有两个程序通过linux管道(命名的或以其他方式)相互传递数据。 I need to hit a transfer rate of ~2600 MB/s between the two programs, but am currently seeing a slower rate of about ~2200 MB/s. 我需要在两个程序之间达到约2600 MB / s的传输速率,但目前看到的速度较慢,约为2200 MB / s。 However, I found that if I replace my 2nd process with 'dd' instead, the transfer rate jumps to over 3000 MB/s. 但是,我发现如果将第二个进程替换为“ dd”,则传输速率将跃升至3000 MB / s以上。 Is there something about the way my program is reading from the pipe that is less efficient than the way 'dd' does it? 我的程序从管道读取数据的方式是否比“ dd”读取方式的效率低? What can I do to improve this throughput? 我该怎么做才能提高吞吐量? Is 'ifstream' inherently slower than other methods of reading binary data from pipe? “ ifstream”在本质上比其他从管道读取二进制数据的方法慢吗?

To summarize the two scenarios: 总结两种情况:

Scenario 1: 方案1:

Program 1 -> [named pipe] -> Program 2 程序1-> [命名管道]->程序2

Yields ~2200 MB/s transfer rate 产量〜2200 MB / s传输速率

Scenario2: 方案2:

Program 1 -> [named pipe] -> 'dd if=pipename of=/dev/null bs=8M' 程序1-> [命名管道]->'dd if =管道名称= / dev / null bs = 8M'

Yields ~3000 MB/s transfer rate. 产生〜3000 MB / s的传输速率。

Here is the way my Program 2 currently reads from pipe: 这是我的程序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
}

Update: 更新:

I have now tried using 'read(fd, &buffer[0], 8*1024*1024)' instead of istream, seemed to show a mild improvement (but not as much as dd) 我现在尝试使用'read(fd,&buffer [0],8 * 1024 * 1024)'代替istream,似乎显示出轻微的改进(但不如dd快)

I also tried using stream->rdbuf()->sgetn(&buffer[0], 8*1024*1024) instead of stream->read(), which did not help. 我也尝试使用stream-> rdbuf()-> sgetn(&buffer [0],8 * 1024 * 1024)代替stream-> read(),这没有帮助。

The difference appears to be due to using an array instead of std::vector, which I still have a hard time believing. 差异似乎是由于使用数组而不是std :: vector造成的,我仍然很难相信。 My two sets of code are shown below for comparison. 下面显示了我的两组代码,以进行比较。 The first can ingest from Program 1 at a rate of about 2500 MB/s. 第一个可以以大约2500 MB / s的速率从程序1接收。 The second can ingest at a rate of 3100 MB/s. 第二个可以3100 MB / s的速率摄取。

Program 1 (2500 MB/s) 程序1(2500 MB / s)

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

Program 2 (3100 MB/s) 程序2(3100 MB / s)

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

Both are compiled with -O3 using gcc version 4.4.6. 两者均使用gcc版本4.4.6与-O3一起编译。 If anyone can explain the reason for this I'd be very interested (since I understand std::vector to basically be a wrapper around an array). 如果有人能解释其原因,我将非常感兴趣(因为我理解std :: vector基本上是数组的包装器)。

Edit : I just tested Program 3, below, that can uses ifstream and runs at 3000 MB/s. 编辑 :我刚刚测试了下面的程序3,该程序可以使用ifstream并以3000 MB / s的速度运行。 So it appears that using ifstream instead of 'read()' incurs a very slight performance degradation. 因此,似乎使用ifstream而不是'read()'会导致非常轻微的性能下降。 Much less than the hit taken from using std::vector. 比使用std :: vector获得的点击量要少得多。

Program 3 (3000 MB/s) 程序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);
    }
}

Edit 2: 编辑2:

I modded Program 2's code to use malloc'd memory instead of memory on the stack and the performance dropped to match the vector performance. 我修改了程序2的代码,以使用malloc的内存而不是堆栈上的内存,并且其性能下降以匹配矢量性能。 Thanks, ipc, for keying me onto this. 谢谢ipc,请您重点介绍一下。

This code compiled with g++ -Ofast : 这段代码使用g++ -Ofast编译:

int main(int argc, char *argv[])
{
  if (argc != 2) return -1;
  std::ifstream in(argv[1]);
  std::vector<char> buf(8*1024*1024);
  in.rdbuf()->pubsetbuf(&buf[0], buf.size());
  std::ios_base::sync_with_stdio(false);
  std::cout << in.rdbuf();
}

does not perform that bad at all. 一点也不差劲。

$ time <<this program>> <<big input file>> >/dev/null
0.20s user 3.50s system 9% cpu 40.548 total
$ time dd if=<<big input file>> bs=8M > /dev/null
0.01s user 3.84s system 9% cpu 40.786 total

You have to consider that std::cout shares a buffer with stdout which is really time consuming if not switched off. 您必须考虑到std::coutstdout共享一个缓冲区,如果不关闭它确实很耗时。 So call std::ios_base::sync_with_stdio(false); 因此调用std::ios_base::sync_with_stdio(false); if you want speed and do not intend to use C's input output methods (which are slower anyway). 如果您想要速度并且不打算使用C的输入输出方法(无论如何都会比较慢)。

Also, for raw and fast input/output in C++, use the methods from streambuf , obtained by rdbuf() . 另外,对于C ++中原始的和快速的输入/输出,请使用streambuf的方法,该方法由rdbuf()获得。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么ifstream :: read比使用迭代器快得多? - Why is ifstream::read much faster than using iterators? 我的代码不会使用 ifstream 和 ofstream 从文件中读取和显示数据 - My code will not read and display data from a file using ifstream and ofstream 为什么将可视化调试器附加到我的程序比直接从Visual Studio运行它更快? - Why is it faster to attach the visual debugger to my program than to run it directly from visual studio? 为什么我的程序在1个线程上比在8个线程上运行更快? - Why my program runs faster on 1 thread than on 8. C++ 为什么我的程序在读取管道的中间冻结? - Why does my program freeze in the middle of a pipe read? 为什么在程序中无法使用“ file_ptr &gt;&gt;变量”从文件读取? - Why I can't read from file using “file_ptr>>variable” in my program? 如何使用ifstream的ifstream使用数据长度而不是新行来读取文件? - How to use ifstream of C++ to read from a file using length of the data rather than new line? 如何使用ifstream从文件中读取行? - How to read lines from a file using the ifstream? 为什么我的程序在 CPU 设备上的运行速度比在 GPU 设备上快得多? - Why does my program run significantly faster on my CPU device than on my GPU device? 为什么我的ifstream程序以错误的顺序读取单词? - Why is my ifstream program reading in words in the wrong order?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM