【问题标题】:How to achieve more efficient file writing in C++? Threads, buffers, memory mapped files?如何在 C++ 中实现更高效的文件写入?线程、缓冲区、内存映射文件?
【发布时间】:2020-10-13 00:18:18
【问题描述】:

我正在开发一个新项目(自学游戏引擎)并尝试创建一个日志系统。我希望记录器尽可能地帮助调试,所以我计划大量使用它来写入日志文件。唯一的问题是我担心文件 I/O 会减慢需要在一定时间内运行的游戏循环。什么是我可以写入文件的最佳方式,同时降低重要部分的速度?

我曾考虑过使用线程,但我担心由于进程调度程序导致的上下文切换开销可能对性能造成更大的阻碍。

我考虑过写入缓冲区并偶尔对文件进行大量转储,但我读到如果缓冲区变得太大,这可能会比常规文件写入更慢。将整个缓冲区保留在内存中并且只在程序结束时将所有内容一次写入文件是否可行?

我读过关于使用内存映射文件的内容,但我也读过它需要有效地完成 boost 库。我想最小化依赖关系,所以理想情况下我不会使用 boost。我也不完全确定我的内存映射文件的概念是否正确。据我了解,它的行为就像您只是在写入内存,但最终内存内容将被写入文件。这个概念正确吗?

感谢您阅读所有这些:)

TL;DR - 我怎样才能实现一个日志系统来最大限度地减少我的程序的性能下降?

【问题讨论】:

  • 这个问题太宽泛,无法回答。我只能给出粗略的建议:将您的日志记录移至线程。通过线程安全结构进行通信。除非需要,否则不要冲洗。只需使用常规缓冲写入,没什么特别的。最重要的是除非您遇到可衡量的性能问题,否则不要花时间优化代码
  • 这个答案可能对stackoverflow.com/questions/1201261/…有帮助
  • “用于调试的记录器”和效率通常是相互排斥的——记录器需要确保数据正确写入文件,然后可以使用该文件来查找问题——例如,如果程序崩溃。这减少了提高效率的选择,比如缓冲。您可以为感知(而非实际)效率做一些事情,例如让日志记录函数在一个线程中排队输出,而另一个线程进行输出。但这会增加丢失输出的风险(可能会破坏日志记录的目的),并且需要大量工作来调试日志记录系统本身及其与其他代码的交互
  • @tadman 是否可以实现不需要主线程等待日志线程发出信号的线程安全缓冲区?
  • 使用线程安全队列的整个想法是没有锁。还有其他结构需要最少的锁定或使用其他工具(如原子变量)来实现它们的线程安全。

标签: c++ file logging game-engine memory-mapped-files


【解决方案1】:

您可以使用 from Ipc 方法并将记录器进程与主进程分开,这两个进程通过队列相互通信。主进程将消息放入队列,记录器进程获取消息并写入文件。

【讨论】:

  • 我不需要用互斥锁保护队列,导致主线程偶尔等待日志线程发出信号吗?
  • 没有必要保护队列。您有两个进程分别工作,一个用于写入,另一个用于从队列中读取,操作系统会处理它。
【解决方案2】:

如果您决定将所有内容写入内存并在最后将整个日志写入文件,那么如果任何应用程序崩溃都会清除所有调试数据。

关于内存映射文件,你在写。但是您必须考虑何时将内存中的页面写入磁盘。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-20
    • 2016-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-23
    • 1970-01-01
    相关资源
    最近更新 更多