在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();
调用比读取一个的40mb文件的内容要快,那么就没有必要在多个CPU上并行化。您的程序执行受到磁盘带宽的限制。你测量过这个吗?*:可以,但是需要硬件。就像在多个CPU上并行执行需要实际的多个CPU硬件一样,并行磁盘I/O需要更多的磁盘I/O硬件。
如果您使用的是传统的HDD,则不会有任何明显的加速,因为会有许多并发的文件读取。硬盘大多不能处理这样的当前文件读取。这就是为什么只有0-5%的CPU占用,这意味着大多数并行循环只是等待文件操作。(注意,只要多个文件读取在不同的物理磁盘或盘片上,磁盘读取就可以并行化。)
有两个解决方案:
- 尝试使用可以支持更好的随机/并发访问的SSD。
- 虽然要解释这个答案中的所有内容并不容易,但请尝试使用管道并行性。OpenMP并不适合流水线,但是TBB支持一个易于使用的流水线模板。管道允许文件读取步骤和其他计算步骤,因此您可以有一个不错的加速。当然,应该有足够的计算量。
相关文章:
- OpenMP阵列性能较差
- OpenMP卸载说'fatal error: could not find accel/nvptx-none/mkoffload'
- 使用 GCC 卸载的 OpenMP 卸载失败,并出现"Ptx assembly aborted due to errors"
- OpenMP:并行更新数组总是需要减少数组吗
- 缓慢提升ASIO
- 如何使用OpenMP并行这两个循环
- 从python调用openMP共享库时,未定义opnMP函数
- 如何使用OpenMP并行化此矩阵时间矢量运算
- 如何使用OpenMP使这个循环并行
- 如何通过替换顺序代码的while循环来添加OpenMP for循环
- 查找最近配对时的OpenMP竞赛条件
- 使用输入打破 OpenMP 中的循环
- 为什么 openmp 的并行不适用于矢量化色彩空间转换?
- 在 openmp 中,omp_get_thread_num是否绑定到物理线程?
- 在C++中使用并行化的预期速度是多少(不是 OpenMp,而是 <thread>)
- OpenMP 加上unordered_map<字符串、双字符串的缩减>
- OpenMP 与有序和关键指令并行
- 我使用 OpenMP 的线程越多,执行时间就越长,这是怎么回事?
- LLVM/OpenMP中的Mutex非常缓慢
- 在OpenMP线程中表现缓慢