简体   繁体   English

重定向标准输出时,为什么我的程序运行得更快?

[英]Why does my program run faster when I redirect stdout?

I'm seeing something really strange. 我看到了一些很奇怪的东西。 I've written a tiny code timer to capture how long blocks of code are running for. 我编写了一个微型代码计时器,以捕获运行了多长时间的代码块。 I can't post all the code, it's pretty big, but I've been through the block in question and there is nothing going near std::cout 我不能发布所有代码,它很大,但是我已经遍历了有问题的代码块,并且std :: cout附近没有内容

$ bin/profiler 50 
50 repetitions of Generate Config MLP took: 254 microseconds
50 repetitions of Create Population took: 5318 microseconds
50 repetitions of Create and Score Population took: 218047 microseconds

$ bin/profiler 50 > time_times
$ cat time_times 
50 repetitions of Generate Config MLP took: 258 microseconds
50 repetitions of Create Population took: 5438 microseconds
50 repetitions of Create and Score Population took: 168379 microseconds

$ bin/profiler 50 
50 repetitions of Generate Config MLP took: 269 microseconds
50 repetitions of Create Population took: 5447 microseconds
50 repetitions of Create and Score Population took: 216262 microseconds

$ bin/profiler 50 > time_times
$ cat time_times 
50 repetitions of Generate Config MLP took: 260 microseconds
50 repetitions of Create Population took: 5321 microseconds
50 repetitions of Create and Score Population took: 169431 microseconds

Here is the block i'm using to time, the function ptr is just a link to a void function, which makes a single function call. 这是我正在使用的时间块,函数ptr只是指向void函数的链接,该函数进行单个函数调用。 I'm aware there are probably better ways to time something, I wanted quick and dirty so I start to improve on the code. 我知道可能有更好的时间计时方式,我希望快速又肮脏,因此我开始改进代码。

void timeAndDisplay(string name,function_ptr f_ptr) {

    struct timeval start, end;
    long mtime, seconds, useconds;

    gettimeofday(&start, NULL);
    // Run the code 
    for (unsigned x = 0; x < reps; x++) {
        f_ptr();
    }

    gettimeofday(&end, NULL);
    seconds  = end.tv_sec  - start.tv_sec;
    useconds = end.tv_usec - start.tv_usec;
    mtime = ((seconds) * 1000000 + useconds/1.0) + 0.0005;

    std::cout << reps << " repetitions of " << name << " took: " << mtime << " microseconds" << std::endl;
}

I'm compiling and linking with: 我正在编译并链接:

g++ -c -Wall  -O3 -fopenmp -mfpmath=sse -march=native src/profiler.cpp -o build/profiler.o
g++ build/*.o -lprotobuf -lgomp -lboost_system -lboost_filesystem  -o bin/profiler

I was about to start making changes so I thought I would save a baseline, but the create and score population is performing differently when I redirect it! 我将要开始进行更改,因此我以为可以保存基准,但是当我重定向它时,创建和计分总体的执行情况会有所不同!

Does anybody know what is going on? 有人知道发生了什么吗?

Update 1: First pass with profiling doesnt show anything significant. 更新1:进行概要分析的第一遍并没有显示任何重要意义。 Almost all the top calls are related to the vector math which the program is running (Eigen library). 几乎所有的调用都与程序正在运行的矢量数学有关(本征库)。 The prevailing theory is that there is some blocking io for the console but the calls to std::cout are outside of the function loop and only 3 in total so I find this hard to accept it has such an impact. 流行的理论是控制台有一些阻塞io,但是对std :: cout的调用不在函数循环之外,总共只有3个,因此我很难接受它会产生如此的影响。

Update 2: After having this drive me crazy for some time, I gave up a bit and started to make improvements to my program with the data I had available. 更新2:在使我发疯了一段时间后,我放弃了一点,开始使用可用数据对程序进行改进。 It got weirder, but I think I've found one the main influencing factors - the available system entropy. 这很奇怪,但我认为我发现了一个主要的影响因素-可用的系统熵。 My program uses huge amounts of random numbers and it seems it runs at a slower pace after running through an amount of times with either method. 我的程序使用了大量的随机数,并且在使用任何一种方法运行了多次之后,它的运行速度似乎都变慢了。 I used a for loop to simulate both methods and although it is quicker with the stdout redirected, I suspect this tiny piece of IO bumps urandom a little which is why its faster. 我使用了for循环来模拟这两种方法,尽管使用stdout重定向可以更快,但是我怀疑这块IO urandom很小,这就是为什么它更快的原因。 I'm still investigating but if anyone can point me in the right direction to prove this I'd be very grateful. 我仍在调查,但如果有人能指出正确的方向来证明这一点,我将不胜感激。

Writing to or from the Standard Console Input/Output system involves buffers and locks. 向标准控制台输入/输出系统写入数据或从标准控制台输入/输出系统写入数据涉及缓冲区和锁定。 So I would say that you're generally taking a performance hit because of locking buffers. 因此,我要说的是,由于锁定缓冲区,通常会导致性能下降。

I would recommend the following Profiler for finding out whats taking the longest amount of time. 我建议使用以下Profiler来找出花费最长时间的内容。

Writing to the console involves graphics manipulations and maybe also handling of carriage returns (moving to the beginning of the line) and linefeed (moving all the previous text up one line and erasing the top line). 写入控制台涉及图形操作,还可能处理回车符(移至行的开头)和换行符(将所有先前的文本上移一行并擦除第一行)。

Redirecting to a file is usually faster because the output is appended and no graphics manipulations take place. 重定向到文件通常更快,因为附加了输出并且不进行任何图形操作。

At least that has been my experience. 至少那是我的经验。

Have you tried running it with the window off the screen or behind another window so it does not have to be drawn? 您是否尝试在窗口不在屏幕上或在另一个窗口后面的情况下运行它,而不必绘制它? I have been on some systems where that would sort of bypass the redrawing of the window. 我曾在一些系统上可以绕过重绘窗口。

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

相关问题 为什么当我启用分析时我的程序运行得更快? - Why does my program run way faster when I enable profiling? 为什么我的程序在 CPU 设备上的运行速度比在 GPU 设备上快得多? - Why does my program run significantly faster on my CPU device than on my GPU device? 为什么我的程序在第一次启动时比下次启动时运行得更快? - Why does my program run faster on first launch than on next launches? 当管道向stdout写入数据时,为什么将write()管道退出程序? - Why does write() to pipe exit program when pipe writes to stdout? 为什么我的程序在递增指针然后删除它时会崩溃? - Why does my program crash when I increment a pointer and then delete it? 为什么当我输入哨兵值时我的程序会崩溃? - Why does my program crash when I enter sentinel value? 为什么我的日志库会导致性能测试运行得更快? - Why does my logging library cause performance tests to run faster? 为什么我的代码在运行时保持循环 - why does my code stay in a loop when i run it 为什么从桌面运行程序时找不到我的声音文件? - Why is my sound file not being found when I run my program from the desktop? 为什么在将boost :: asio用于STDIN / STDOUT的程序传递到程序时,read()会因EAGAIN而失败? - Why does read() fail with EAGAIN when piping to a program using boost::asio for STDIN/STDOUT?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM