繁体   English   中英

在OpenMP线程中降低性能

[英]fread slow performance in OpenMP threads

我使用Intel Xeon x2(24内核)和Windows Server 2008。
试图并行化我的c ++程序。 这里的模板代码:

vector< string > files;
vector< vector< float > > data; 
...
data.resize( files.size() ); 

#pragma omp parallel for 
for (int i=0; i<files.size(); i++) { // Files count is about 3000
    FILE *f = fopen(files[i].c_str(), "rb"); 

    // every file is about 40 mb
    data[i].resize(someSize);
    fread(&data[i][0], sizeof(float), someSize, f); 

    fclose(f);
    ...
    performCalculations();  
}

CPU使用率仅为0到5%。
当我插入而不是fread(&data [i] [0],sizeof(float),someSize,f)

for (int j=0; j<data.size(); j++) {
    data[i][j] = rand(); 
}

CPU使用率增加到100%。
我已经尝试过使用fstream和WinApi ReadFile,但它没有产生太大影响。

我究竟做错了什么? 我不相信磁盘读数会这么慢......

我不相信磁盘读数会这么慢......

然后你最好开始相信。 与CPU相比,磁盘速度极慢。 并行I / O通常仅在您从多个源(如单独的磁盘或网络连接)读取时才有帮助。 它可以很好地解决延迟问题,但不能解决带宽问题。

尝试一次性读取所有数据,然后连续读取,然后在并行循环中处理它。

磁盘读数无法并行化*:您是否拥有1或24个CPU内核不会改变磁盘I / O吞吐量。

如果一个 performCalculations(); 调用比读取其中一个 40 MB文件的内容要快,然后就不需要在多个CPU上并行化了。 您的程序执行受磁盘带宽的限制。 你测量过这个吗?

*:他们可以,但需要硬件。 就像在多个CPU上并行执行需要实际的多CPU硬件一样,并行化磁盘I / O需要更多的磁盘I / O硬件。

如果您使用传统的HDD,则不会有任何可见的加速,因为会有许多并发文件读取。 HDD主要无法处理此类当前文件读取。 这就是为什么你只有0-5%的CPU使用率,这意味着大多数并行循环只是等待文件操作。 (请注意,只要多个文件读数位于不同的物理磁盘或盘片上,磁盘读数就可以并行化。)

有几个解决方案:

  1. 尝试使用可以支持更好的随机/并发访问的SSD。
  2. 虽然在这个答案中解释一切并不容易,但尝试使用管道并行性 OpenMP不适合流水线操作,但TBB支持易于使用的管道模板。 Pipeline允许文件读取步骤和其他计算步骤,因此您可以获得不错的加速。 当然,应该有足够的计算。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM