Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ fread在OpenMP线程中的性能较慢_C++_Performance_File_Openmp - Fatal编程技术网

C++ fread在OpenMP线程中的性能较慢

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

我使用英特尔至强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();  
}
vector文件;
矢量<矢量<浮点>>数据;
...
data.resize(files.size());
#pragma-omp并行
对于(int i=0;i
我不相信磁盘读取会这么慢

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


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

磁盘读取无法并行*:无论您有1个或24个CPU内核,都不会改变磁盘I/O吞吐量

如果one
performCalculations();
调用比读取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(); 
    }