gpt4 book ai didi

c++ - 来自文件的并发处理

转载 作者:可可西里 更新时间:2023-11-01 09:38:29 24 4
gpt4 key购买 nike

考虑以下代码:

std::vector<int> indices = /* Non overlapping ranges. */;
std::istream& in = /*...*/;

for(std::size_t i= 0; i< indices.size()-1; ++i)
{
in.seekg(indices[i]);

std::vector<int> data(indices[i+1] - indices[i]);

in.read(reinterpret_cast<char*>(data.data()), data.size()*sizeof(int));

process_data(data);
}

我想让这段代码尽可能快地并行化。

使用 PPL 并行化它的一种方法会是:

std::vector<int> indices = /* Non overlapping ranges. */;
std::istream& in = /*...*/;
std::vector<concurrency::task<void>> tasks;

for(std::size_t i= 0; i< indices.size()-1; ++i)
{
in.seekg(indices[i]);

std::vector<int> data(indices[i+1] - indices[i]);

in.read(reinterpret_cast<char*>(data.data()), data.size()*sizeof(int));

tasks.emplace_back(std::bind(&process_data, std::move(data)));
}
concurrency::when_all(tasks.begin(), tasks.end()).wait();

这种方法的问题是我想在读入内存(数据在缓存中很热)的同一个线程中处理数据(适合 CPU 缓存),但这里不是这种情况,这只是在浪费使用热点数据的机会。

我有两个想法如何改进它,但是,我都没有实现。

  1. 在单独的任务上开始下一次迭代。

    /* ??? */
    {
    in.seekg(indices[i]);

    std::vector<int> data(indices[i+1] - indices[i]); // data size will fit into CPU cache.

    in.read(reinterpret_cast<char*>(data.data()), data.size()*sizeof(int));

    /* Start a task that begins the next iteration? */

    process_data(data);
    }
  2. 使用内存映射文件并映射文件的所需区域,而不是直接从具有正确偏移量的指针读取。使用 parallel_for_each 处理数据范围。但是,我不了解内存映射文件在何时读取到内存和缓存注意事项方面的性能影响。也许我什至不必考虑缓存,因为文件只是通过 DMA:d 传输到系统内存,从不通过 CPU?

有什么建议或意见吗?

最佳答案

您很可能正在追求错误的目标。如前所述,“热数据”的任何优势都会因磁盘速度而相形见绌。否则,您有重要的细节没有告诉。
1) 文件是否'大'
2)单条记录是否'大'
3)处理是否“慢”

如果文件“大”,您的首要任务是确保按顺序读取文件。你的“指数”让我不这么认为。根据我自己的经验,最近的例子是 6 秒和 20 分钟,具体取决于随机读取和顺序读取。别开玩笑了。

如果文件“小”并且您确定它已完全缓存,您只需要一个同步队列来将任务传递给您的线程,那么在同一个线程中处理就不会成为问题。

另一种方法是将“索引”分成两半,每个线程一个。

关于c++ - 来自文件的并发处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11937921/

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