gpt4 book ai didi

C: 为什么 fprintf(stdout,....) 这么慢?

转载 作者:太空狗 更新时间:2023-10-29 16:48:28 28 4
gpt4 key购买 nike

我仍然经常使用控制台输出来了解我的代码中发生了什么。我知道这可能有点过时,但我也用它来“管道”标准输出进入日志文件等。

然而,事实证明,某些情况下控制台的输出变慢了原因。我想知道是否有人可以解释为什么 fprintf() 到控制台窗口似乎有点阻塞。

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

  1. 我测量了一个简单的时间fprintf(stdout,"快速 fprintf\n");它需要:0.82ms(平均)。这被认为太久了,因为 vsprintf_s(...) 在短短几微秒内将相同的输出写入字符串。因此,必须有一些专门针对控制台的阻塞。

  2. 为了避免阻塞,我使用 vsprintf_s(...) 将我的输出复制到类似 fifo 的数据结构中。数据结构受临界区对象保护。然后,一个单独的线程通过将排队的输出放到控制台来取消排队数据结构。

  3. 我可以通过引入管道服务获得进一步的改进。我的程序的输出(应该在控制台窗口中结束)如下所示:

    • vsprintf_s(...) 将输出格式化为简单的字符串。
    • 字符串被排入类似 fifo 的数据结构中,例如链表结构。此数据结构受临界区对象保护。
    • 第二个线程通过将输出字符串发送到命名管道来使数据结构出队。
    • 第二个进程读取命名管道并将字符串再次放入类似数据的 fifo 中结构体。这是为了让读数远离控制台的阻塞输出。读取过程在读取命名管道时速度很快,并连续监视管道缓冲区的填充水平。
    • 第二个进程中的第二个线程最终通过 fprintf(stdout,...) 将数据结构出列到控制台。

所以我有两个进程,每个进程至少有两个线程,它们之间有一个命名管道,管道两边都有类似 fifo 的数据结构,以避免在管道缓冲区已满时阻塞。

要确保控制台输出是“非阻塞的”,需要做很多事情。但结果是还不错。我的主程序可以在几微秒内编写复杂的 fprintf(stdout,...)。

也许我应该早点问:有没有其他(更简单!)的方法来获得非阻塞控制台输出?

最佳答案

我认为计时问题与默认情况下 行缓冲 控制台有关。这意味着每次您向其写入一个 '\n' 字符时,您的整个输出缓冲区都会发送到控制台,这是一个相当昂贵的操作。这是您为使该行立即出现在输出中而付出的代价。

您可以通过将缓冲策略更改为完全缓冲 来更改此默认行为。结果是输出将以与缓冲区大小相等的 block 的形式发送到控制台,但单个操作将更快完成。

在您第一次写入控制台之前进行此调用:

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

个别写入的时间应该有所改善,但输出不会立即出现在控制台中。这对调试用处不大,但时序会有所改善。如果您设置了一个定期调用 fflush(stdout) 的线程,比如说,每秒一次,您应该在单个写入的性能和程序写入之间的延迟之间取得合理的平衡输出以及您实际可以在控制台上看到它的时间。

关于C: 为什么 fprintf(stdout,....) 这么慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11558540/

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