C:为什么一个fprintf中(标准输出,....)这么慢? [英] C: Why is a fprintf(stdout,....) so slow?

查看:1552
本文介绍了C:为什么一个fprintf中(标准输出,....)这么慢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我仍然经常使用控制台输出来获得的想法发生了什么事在我的code。
我知道这可能是有点老的时尚,但我也用这个来管标准输出
到日志文件等。

I still often use console output to get ideas what's going on in my code. I know this may be a bit old fashion, but I also use this to "pipe" stdout into log files etc.

然而,事实证明,输出到控制台放慢一些
原因。我想知道,如果有人可以解释为什么一个fprintf中()到控制台
窗口出现被排序的阻塞。

However, it turns out that the output to the console is slowed down for some reason. I was wondering if someone can explain why an fprintf() to a console window appears to be sort of blocking.

我所做/到目前为止诊断:

What I've done/diagnosed so far:


  1. 我测量的时间简单
    fprintf中(标准输出,快fprintf中\\ n);
    它的需要:0.82ms(平均)。这是迄今为止太长,因为考虑vsprintf_s(...)将输出到在短短几微秒的字符串相同。因此,必须有专门的一些堵到控制台。

  1. I measured the time a simple fprintf(stdout,"quick fprintf\n"); It needs: 0.82ms (in average). This is considered by far too long since a vsprintf_s(...) writes the same output into a string in just a few microseconds. Therefore there must be some blocking specifically to the console.

在奥得河,从我使用 vsprintf_s阻塞逃生(...)来我的输出复制到一个FIFO相似的数据结构。该数据结构由一个临界区对象的保护。一个单独的线程然后通过将排队输出到控制台unqueing的数据结构

In oder to escape from the blocking I have used vsprintf_s(...) to copy my output into a fifo alike data structure. The data structure is protected by a critical section object. A separate thread is then unqueing the data structure by putting the queued output to the console.

一个进一步的改善,我可以通过引入管道服务获得。
我的程序(应该在控制台窗口结束)的输出变为方式如下:

One further improvement I could obtain by the introduction of pipe services. The output of my program (supposed to end up in a console window) goes the following way:


  • A vsprintf_s(...)格式输出,以简单的字符串。

  • 的字符串被排队到FIFO一样的数据结构,一个链表sructure例如。这个数据结构是由一个临界区对象的保护。

  • 第二个线程发送输出字符串,命名管道离队的数据结构。

  • 第二个进程读取命名管道,并再次把字符串到一个FIFO数据的一致好评
    结构体。这需要从阻塞输出到控制台保持读了。
    读取过程是快速的读取命名管道并监视管的填充水平连续缓冲。

  • 在第二个进程的第二个线程最后通过出列 fprintf中(标准输出,...)的数据结构到控制台上。

  • A vsprintf_s(...) formats the output to simple strings.
  • The strings are queued into a fifo alike data structure, a linked list sructure for example. This data structure is protected by a critical section object.
  • A second thread dequeues the data structure by sending the output strings to a named pipe.
  • A second process reads the named pipe and puts the strings again into a fifo alike data structure. This is needed to keep the reading away from the blocking output to the console. The reading process is fast at reading the named pipe and monitors the fill level of the pipes buffer continuously.
  • A second thread in that second process finally dequeues the data structure by fprintf(stdout,...) to the console.

所以,我有与每个至少有两个线程,它们之间的一个命名管道两个过程,和FIFO在管的两侧都数据结构,以避免在管道缓冲区满事件阻断

So I have two processes with at least two threads each, a named pipe between them, and fifo alike data structures on both sides of the pipe to avoid blocking in the event of pipe buffer full.

这是一个很大的东西只是确保控制台输出是非阻塞。但结果是
不算太糟糕。我的主程序只需几微秒内编写复杂的fprintf中(标准输出,...)。

That is a lot of stuff to just make sure that console output is "non-blocking". But the result is not too bad. My main program can write complex fprintf(stdout,...) within just a few microseconds.

也许我应该早一点问:有没有一些其他的(!更容易)的方式有无阻塞控制台输出

Maybe I should have asked earlier: Is there some other (easier!) way to have nonblocking console output?

推荐答案

我觉得时机问题与事实控制台的行缓冲的默认情况下做的。这意味着,每次你写一个的'\\ n'字符给它,你的整个输出缓冲器发送到控制台,这是一个相当昂贵的操作。这是您支付线的价格立即出现在输出中。

I think the timing problem has to do with the fact that console is line buffered by default. This means that every time you write a '\n' character to it, your entire output buffer is sent to the console, which is a rather costly operation. This is the price that you pay for the line to appear in the output immediately.

您可以通过改变缓冲策略来的全缓冲的更改此默认行为。其结果是,该输出将被发送在等于你的缓冲区的大小的块到控制台,但个别的操作将完成得更快。

You can change this default behavior by changing the buffering strategy to full buffering. The consequence is that the output will be sent to console in chunks that are equal to the size of your buffer, but individual operations will complete faster.

请此调用之前你先写控制台:

Make this call before you first write to console:

char buf[10000];
setvbuf(stdout, buf, _IOFBF, sizeof(buf));

个人写的时间应提高,但产量不会立即出现在控制台中。这是不适合的调试也是有用的,但时间将得到改善。如果您设置了调用 fflush(标准输出)在固定的时间间隔,也就是说,每秒一次一个线程,你应该得到个别写入的性能和合理的平衡你的程序写入输出,当你可以看到它在控制台上的时间之间的延时。

The timing of individual writes should improve, but the output will not appear in the console immediately. This is not too useful for debugging, but the timing will improve. If you set up a thread that calls fflush(stdout) on regular time intervals, say, once every second, you should get a reasonable balance between the performance of individual writes and the delay between your program writing the output and the time when you can actually see it on the console.

这篇关于C:为什么一个fprintf中(标准输出,....)这么慢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆