c++ - 以固定速率重播存储的数据

标签 c++ multithreading performance io locking

我正在解决一个问题,我想以指定的速率重放存储在文件中的数据。

例如:25,000 条记录/秒。

文件为ascii格式。目前,我阅读了文件的每一行并将正则表达式应用于 提取数据。 2~4行组成一条记录。我为这个操作计时,它需要接近 生成每条记录需要 15 微秒。

发布每条记录所花费的时间为 6 微秒。

如果我按顺序执行读取和写入,那么我最终会用 21 微秒来发布每条记录。如此有效,这意味着我的上限是每秒约 47K 条记录。

如果我决定多线程读取和写入,那么我将能够每 9 微秒发送一个数据包(忽略锁定惩罚,因为读取器和写入器共享相同的 Q),这提供了每秒 110K 滴答的吞吐量。

我之前的设计是否正确?

当单个生产者和消费者共享一个队列时,哪种队列和锁定结构的惩罚最小?

如果我想扩大规模,最好的方法是什么?

我的应用程序是用 C++ 编写的

最佳答案

如果读取/准备记录需要 15uS,那么您的最大吞吐量约为 1sec/15uSec = 67k/sec。您可以忽略 6uSec 部分,因为读取文件的单线程不能生成比这更多的记录。 (尝试一下,将程序更改为仅读取/处理并丢弃输出)不确定您是如何获得 9uS 的。

要使它的飞行速度超过 67k/sec ...

A) 估计每秒可以从要格式化的磁盘读取的最大记录数。虽然这在很大程度上取决于硬件,但 20Mb/秒的数字对于普通笔记本电脑来说是典型的。这个数字会给你目标的上限,当你接近时,你可以放松尝试。

B) 创建一个线程来读取文件并导致 IO 延迟。这个线程应该写入大的预分配缓冲区,比如每个 4Mb。参见 http://en.wikipedia.org/wiki/Circular_buffer管理这些的方法。您希望每个缓冲区保存 1000 条记录(猜猜,但不仅仅是 8 条记录!)伪代码:

   while not EOF
     Allocate big buffer
     While not EOF and not buffer full
          Read file using fgets() or whatever
          Apply only very small preprocessing, ideally none
          Save into buffer
     Release buffer for other threads

C) 创建另一个线程(如果记录的顺序不重要,则创建多个线程)以在环形缓冲区已满时处理它,这是您的正则表达式步骤。该线程依次写入另一组输出环形缓冲区(提示,在内存中将环形缓冲区控制结构分开)

    While run-program
        Wait/get an input buffer to process, semaphores/mutex/whatever you prefer
        Allocate output buffer
        Process records from input buffer,
           Place result in output buffer
        Release output buffer for next thread
        Release input buffer for reading thread

D) 创建最终线程来使用数据。目前尚不清楚此输出是写入磁盘还是网络,因此这可能会影响磁盘读取线程。

    Wait/get input buffer from processed records pool
    Output records to wherever
    Return buffer to processed records pool

注释。 预分配所有缓冲区并将它们传回它们来自的地方。例如,您可能在文件读取线程和处理线程之间有 4 个缓冲区,当所有 4 个都被注入(inject)时,文件读取器等待一个空闲,它不只是分配新的缓冲区。 如果可以避免,请尽量不要使用 memset() 缓冲区,这会浪费内存带宽。 你不需要很多缓冲区,6?每个环形缓冲区?

系统将自动调整到最慢的线程 (http://en.wikipedia.org/wiki/Theory_of_constraints),因此如果您读取和准备数据的速度比您希望的输出速度快,所有缓冲区都将填满并且除输出外的所有内容都将暂停。

由于线程在每个同步点传递合理数量的数据,因此开销不会太大。

上面的设计是我的一些代码如何尽可能快地读取CSV文件,基本上都是以输入IO带宽为限制因素。

关于c++ - 以固定速率重播存储的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15180291/

相关文章:

c# - 如何将 C++ 指针分配给 C# 函数

c# - Thread.Sleep(Timespan.Zero) 可以在这种情况下明智地使用吗?

java - 同时执行 2 个任务列表

java - 从不同线程一起使用 Hibernate 和 JDBC

java - 有效线程数

c++ - 动态转换、对象列表转换、模板

c++ - 该算法用于查找所有路径总和的时间复杂度是多少?

.net - Azure 应用服务的响应非常慢

Android HttpClient 性能

c++ - 为什么这段代码没有在二叉搜索树中插入节点