一切都一样,在 C++ 中将数据输出到磁盘的最快方法是什么?

发布于 2024-08-24 00:40:32 字数 217 浏览 4 评论 0原文

我正在运行的模拟代码很大程度上受 CPU 速度的限制。我对将数据输入/输出到用户界面不感兴趣,只需在计算时将其保存到磁盘即可。

减少开销的最快解决方案是什么? iostreams?打印?我之前读过 printf 更快。这取决于我的代码吗?如果不进行分析就不可能得到答案吗?

这将在 Windows 中运行,输出数据需要采用文本格式,制表符/逗号分隔,并针对大多数浮点值提供格式/精度选项。

I am running simulation code that is largely bound by CPU speed. I am not interested in pushing data in/out to a user interface, simply saving it to disk as it is computed.

What would be the fastest solution that would reduce overhead? iostreams? printf? I have previously read that printf is faster. Will this depend on my code and is it impossible to get an answer without profiling?

This will be running in Windows and the output data needs to be in text format, tab/comma separated, with formatting/precision options for mostly floating point values.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

凉风有信 2024-08-31 00:40:32

构建可以顺序写入的(大型)数据块并使用异步 IO。

准确的分析会很痛苦,请阅读一些有关该主题的论文:scholar.google.com

Construct (large-ish) blocks of data which can be sequentially written and use asynchronous IO.

Accurately Profiling will be painfull, read some papers on the subject: scholar.google.com.

两相知 2024-08-31 00:40:32

我自己没有使用过它们,但我听说内存映射文件为操作系统提供了最佳的优化机会。

编辑:相关问题关于内存映射文件的维基百科文章 - 都提到了性能优势。

I haven't used them myself, but I've heard memory mapped files offer the best optimisation opportunities to the OS.

Edit: related question, and Wikipedia article on memory mapped files — both mention performance benefits.

拿命拼未来 2024-08-31 00:40:32

我的想法是你正在解决错误的问题。为什么要写出大量文本格式的数据?如果是因为您希望它是人类可读的,请编写一个快速浏览器程序来即时读取二进制格式的数据 - 这样模拟应用程序可以快速写出二进制数据,而浏览器可以完成格式化数据的繁重工作需要时提供数据。如果是因为您正在使用某些统计包来读取和分析文本数据,那么请编写一个输入二进制数据的包。

My thought is that you are tackling the wrong problem. Why are you writing out vast quantities of text formatted data? If it is because you want it to be human readable, writing a quick browser program to read the data in binary format on the fly - this way the simulation application can quickly write out binary data and the browser can do the grunt work of formatting the data as and when needed. If it is because you are using some stats package to read and analyse text data then write one that inputs binary data.

顾冷 2024-08-31 00:40:32

Scott Meyers 的《更高效的 C++》第 23 点“考虑替代库”建议,如果您更看重速度而不是安全性和可扩展性,请使用 stdio 而不是 iostream。值得检查一下。

Scott Meyers' More Effective C++ point 23 "Consider alternate libraries" suggests using stdio over iostream if you prefer speed over safety and extensibility. It's worth checking.

半山落雨半山空 2024-08-31 00:40:32

最快的方法是对于在其典型目标操作系统和硬件上运行的特定应用程序而言最快的方法。唯一明智的做法是尝试多种方法并计时。您可能不需要完整的个人资料,并且练习应该只需要几个小时。我将按以下顺序进行测试:

  • 正常的 C++ 流 I/O
  • 使用 ostream::write() 的正常流 I/
  • O 使用 CI/O 库
  • 使用 write() 等系统调用
  • 异步 I/O

我会停止当我找到一个足够快的解决方案时。

The fastest way is what is fastest for your particular application running on its typical target OS and hardware. The only sensible thing to do do is to try several approaches and time them. You probably don't need a complete profile, and the exercise should only take a few hours. I would test, in this order:

  • normal C++ stream I/O
  • normal stream I/O using ostream::write()
  • use of the C I/O library
  • use of system calls such as write()
  • asynch I/O

And I would stop when I found a solution that was fast enough.

桃气十足 2024-08-31 00:40:32

文本格式意味着它是供人类消费的。人类的阅读速度远远低于任何合理的输出方式的速度。有一个地方是矛盾的。我怀疑“输出必须是文本格式”。

因此,我相信正确的方法是输出二进制文件,并提供单独的查看器将单个条目转换为可读文本。查看器中的格式设置只需与人们可以阅读的速度一样快。

Text format means it's for human consumption. The speed at which humans can read is far, far lower than the speed of any reasonable output method. There's a contradiction somewhere. I suspect the "output must be text format".

Therefore, I beleive the correct was is to output binary, and provide a separate viewer to convert individual entries to readable text. Formatting in the viewer need only be as fast as people can read.

七分※倦醒 2024-08-31 00:40:32

将文件映射到内存(即使用 内存映射文件),然后只需 memcopy-ing 数据是一种非常快速的读/写方式。

您可以使用多个线程/核心写入数据,操作系统/内核将使用与虚拟内存相同的例程将页面同步到磁盘,可以期望对其进行优化,更多或较少的。

主要是,执行此操作时,内存中应该有很少的额外副本/缓冲区。一旦页面被写入,写入就会被中断捕获并添加到磁盘队列中。

Mapping the file to memory (i.e. using a Memory Mapped File) then just memcopy-ing data there is a really fast way of reading/writing.

You can use several threads/cores to write to the data, and the OS/kernel will sync the pages to disk, using the same kind of routines used for virtual memory, which one can expect to be optimized to hell and back, more or less.

Chiefly, there should be few extra copies/buffers in memory when doing this. The writes are caught by interrupts and added to the disk queue once a page has been written.

有木有妳兜一样 2024-08-31 00:40:32

以二进制模式打开文件,并将“未格式化”的数据写入光盘。

fstream myFile;
...
myFile.open ("mydata.bin", ios:: in | ios::out | ios::binary);
...
class Data {
    int      key;
    double   value;
    char[10] desc;
};

Data x;

myFile.seekp (location1);
myFile.write ((char*)&x, sizeof (Data));

编辑:OP 添加了“输出数据需要采用文本格式,无论是制表符还是逗号分隔。”约束。

如果您的应用程序受 CPU 限制,则输出格式化是您不需要的开销。二进制数据的写入和读取速度比 ascii 快得多,在光盘上更小(例如,用二进制写入的总字节数比用 ascii 少),并且因为它更小,所以在网络上移动速度更快(包括安装在网络上的网络)。文件系统)。所有指标都表明二进制是一种良好的整体优化。

运行后可以使用一个简单的实用程序查看二进制数据,该实用程序会将数据转储为所需的任何格式的 ascii。我鼓励将一些版本信息添加到生成的二进制数据中,以确保可以在转储实用程序中处理数据格式的更改。

从二进制转向 ascii,然后争论 printf 与 iostream 的相对性能可能不是您时间的最佳利用方式。

Open the file in binary mode, and write "unformatted" data to the disc.

fstream myFile;
...
myFile.open ("mydata.bin", ios:: in | ios::out | ios::binary);
...
class Data {
    int      key;
    double   value;
    char[10] desc;
};

Data x;

myFile.seekp (location1);
myFile.write ((char*)&x, sizeof (Data));

EDIT: The OP added the "Output data needs to be in text format, whether tab or comma separated." constraint.

If your application is CPU bound, the formatting of output is an overhead that you do not need. Binary data is much faster to write and read than ascii, is smaller on the disc (e.g. there are fewer total bytes written with binary than with ascii), and because it is smaller it is faster to move around a network (including a network mounted file system). All indicators point to binary as a good overall optimization.

Viewing the binary data can be done after the run with a simple utility that will dump the data to ascii in whatever format is needed. I would encourage some version information be added to the resulting binary data to ensure that changes in the format of the data can be handled in the dump utility.

Moving from binary to ascii, and then quibbling over the relative performance of printf versus iostreams is likely not the best use of your time.

苦笑流年记忆 2024-08-31 00:40:32

最快的方法是基于完成的异步 IO。

通过向操作系统提供一组要写入的数据(在调用返回时实际上尚未写入这些数据),操作系统可以对其进行重新排序以优化写入性能。

用于执行此操作的 API 是特定于操作系统的:在 Linux 上,其称为 AIO;在 Windows 上,其称为完成端口

The fastest way is completion-based asynchronous IO.

By giving the OS a set of data to write, which it hasn't actually written when the call returns, the OS can reorder it to optimise write performance.

The API for doing this is OS specific: on Linux, its called AIO; on Windows its called Completion Ports.

梦归所梦 2024-08-31 00:40:32

一种快速方法是使用双缓冲和多线程(至少两个)。

其中一个线程负责将数据写入硬盘。此任务检查缓冲区,如果不为空(或可能有其他规则),则开始写入硬盘驱动器。

另一个线程将格式化文本写入缓冲区。

硬盘驱动器的一个性能问题是加快速度并将磁头定位到正确位置所需的时间。为了避免这种情况发生,目标是不断写入硬盘,使其不会停止。这很棘手,并且可能涉及程序范围之外的内容(例如同时运行的其他程序)。写入硬盘的数据块越大越好。

另一个难题是在硬盘驱动器上寻找空插槽来放置数据。有碎片的硬盘驱动器会比格式化或碎片整理的驱动器慢。

如果可移植性不是问题,您可以检查操作系统中是否有一些对硬盘执行块写入的 API。或者您可以继续深入并使用直接写入驱动器的 API。

您可能还希望您的程序更改其优先级,以便它成为正在运行的最重要的任务之一。

A fast method is to use double buffering and multiple threads (at least two).

One thread is in charge of writing data to the hard drive. This task checks the buffer and if not empty (or another rule perhaps) begins writing to the hard drive.

The other thread writes formatted text to the buffer.

One performance issue with hard drives is the amount of time required to get up to speed and position the head to the correct location. To avoid this from happening, the objective is to continually write to the hard drive so that it doesn't stop. This is tricky and may involve stuff outside of your program's scope (such as other programs running at the same time). The larger the chunk of data written to the hard drive, the better.

Another thorn is finding empty slots on the hard drive to put the data. A fragmented hard drive would be slower than a formatted or defragmented drive.

If portability is not an issue, you can check your OS for some APIs that perform block writes to the hard drive. Or you can go down lower and use the API that writes directly to the drive.

You may also want your program to change it's priority so that it is one of the most important tasks running.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文