首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >文件并发处理

文件并发处理
EN

Stack Overflow用户
提问于 2012-08-13 15:55:22
回答 1查看 337关注 0票数 3

考虑以下代码:

代码语言:javascript
复制
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将其平分的一种方法是:

代码语言:javascript
复制
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(indicesi);std::vector (indicesi+1- indicesi);//数据大小将适合于CPU缓存。in.read(reinterpret_cast(data.data()),data.size()*sizeof(int));/*启动开始下一次迭代的任务?*/ process_data(数据);}
  2. 使用内存映射文件并映射文件的所需区域,而不是只从指针中读取具有正确偏移量的内容。使用parallel_for_each处理数据范围。但是,我不理解内存映射文件在何时被读取到内存和缓存方面的性能影响。也许我甚至不需要考虑缓存,因为文件只是DMA:d到系统内存,从来没有通过CPU?

有什么建议或意见吗?

EN

回答 1

Stack Overflow用户

发布于 2012-08-22 12:27:23

很有可能你追求的是错误的目标。如前所述,“热数据”的任何优势都将与磁盘速度相形见绌。否则,有一些重要的细节你没有告诉。

1)文件是否“大”

2)单个记录是否“很大”

3)处理是否“慢”

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

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

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11937921

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档