C++ 文件的并发处理

C++ 文件的并发处理,c++,windows,file,memory-mapped-files,ppl,C++,Windows,File,Memory Mapped Files,Ppl,考虑以下代码: 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]);

考虑以下代码:

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);
}
std::vector index=/*非重叠范围。*/;
std::istream&in=/*…*/;
对于(std::size_t i=0;i
我想让这段代码尽可能快地并行

使用以下方法对其进行平行分析:

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();
std::vector index=/*非重叠范围。*/;
std::istream&in=/*…*/;
向量任务;
对于(std::size_t i=0;i
这种方法的问题是,我希望在将数据读入内存(缓存中的数据是热的)的同一线程中处理数据(适合CPU缓存),但这里的情况并非如此,这只是浪费了使用热数据的机会

我有两个想法如何改善这一点,然而,我也没有意识到这一点

  • 在单独的任务上开始下一次迭代

    /* ??? */
    {
         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);
    }
    
    /**/
    {
    in.seekg(指数[i]);
    std::vector data(索引[i+1]-索引[i]);//数据大小将适合CPU缓存。
    in.read(reinterpret_cast(data.data())、data.size()*sizeof(int));
    /*启动一个开始下一次迭代的任务*/
    过程数据(数据);
    }
    
  • 使用内存映射文件并映射文件的所需区域,而不是仅查找从指针读取的正确偏移量。对每个使用一个并行_处理数据范围。但是,我不理解内存映射文件在何时读取到内存和缓存方面的性能影响。也许我甚至不用考虑缓存,因为文件仅仅是DMA:D到系统内存,从来没有通过CPU?


  • 有什么建议或意见吗?

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

    如果文件是“大”文件,您最大的优先级是确保按顺序读取该文件。你的“指数”让我不这么想。根据我自己的经验,最近的例子是6秒对20分钟,这取决于随机读取和顺序读取。别开玩笑了

    如果文件是“小”文件,并且您确信它是完全缓存的,那么您只需要一个同步队列来将任务交付给您的线程,那么在同一线程中处理就不会有问题


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

    为什么不尝试将文件拆分为较小的文件,然后在单独的线程中读取和处理它们?对于文件,您必须考虑CPU绑定和I/O绑定+1。似乎将内存保留在缓存中所获得的任何好处都会与等待文件I/O相形见绌。@BenFulton:你是对的,假设文件不在OS缓存中和/或我没有执行此函数的多个并发执行。