C++ fread在OpenMP线程中的性能较慢
我使用英特尔至强x2(24内核)和Windows Server 2008。C++ fread在OpenMP线程中的性能较慢,c++,performance,file,openmp,C++,Performance,File,Openmp,我使用英特尔至强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
尝试并行化我的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();
}
vector文件;
矢量<矢量<浮点>>数据;
...
data.resize(files.size());
#pragma-omp并行
对于(int i=0;i
我不相信磁盘读取会这么慢
那么你最好开始相信。与CPU相比,磁盘速度非常慢。并行I/O通常只在从多个源(如单独的磁盘或网络连接)读取数据时才有帮助。它可以很好地解决延迟问题,但不能解决带宽问题
尝试一次性串行读取所有数据,然后在并行循环中处理。磁盘读取无法并行*:无论您有1个或24个CPU内核,都不会改变磁盘I/O吞吐量
如果oneperformCalculations();
调用比读取40MB文件中one的内容快,则无需在多个CPU上并行。您的程序执行受到磁盘带宽的限制。您测量过这一点吗
*:它们可以,但需要硬件。就像在多个CPU上并行执行需要实际的多CPU硬件一样,并行磁盘I/O需要更多的磁盘I/O硬件。如果您使用的是传统的HDD,则不会有任何可见的加速,因为会有许多并发文件读取。HDD通常无法处理如此多的当前数据文件读取。这就是为什么您只有0-5%的CPU使用率,这意味着大多数并行循环只是等待文件操作。(请注意,只要多个文件读取在不同的物理磁盘或磁盘上,磁盘读取就可以并行化。)
有两种解决方案:
尝试使用能够更好地支持随机/并发访问的SSD
虽然在这个答案中解释所有内容并不容易,但请尝试使用。OpenMP不适合管道化,但TBB支持易于使用的管道模板。管道允许文件读取步骤和其他计算步骤,因此您可以有一个不错的加速。当然,应该有足够的计算
“尝试一次读取所有数据”-是的,我已经这样做了:)我的朋友给了我一个很好的提示:使用ramdisk存储文件。3000个40 MB的文件可以生成120 GB。即使不是特别的,RAM的数量也是相当大的。你所说的管道并行性是什么意思?你能编辑一下你的答案来更详细些吗?
for (int j=0; j<data.size(); j++) {
data[i][j] = rand();
}