读取文件时无法使用 OpenMP 获得加速

Posted

技术标签:

【中文标题】读取文件时无法使用 OpenMP 获得加速【英文标题】:Couldn't get acceleration using OpenMP while reading files 【发布时间】:2018-10-14 04:17:02 【问题描述】:

我尝试使用 OpenMP 在 C++ 中读取一个 500M 的文件。我将文件分成几个块,每次并行加载“杀死”记录,重复。

我正在 ubuntu 上使用 gcc 编译文件(g++ mytest.cpp -o mytest -fopenmp)。

这里我提供代码:

(我删除了一些代码以使 ReadFile 功能更加突出。)

map<unsigned int, int> Node2Num;
typedef struct 
    unsigned int num;
    set<unsigned int>adj;
node; 
node Gnode[4800000];

void ReadFile()

    ifstream input("./soc-LiveJournal1.bin", ios::in | ios::binary);
    cout << "start to read the file..." << endl;

    //to get the size of the file
    input.seekg(0, ios_base::end);
    size_t fileSize = input.tellg();
    input.seekg(0, ios_base::beg);

    //to split the file into ReadTime blocks
    int EdgesInFile = fileSize / 8; 
    int ReadTime = EdgesInFile / PerEdges;
    unsigned int buffer[2*PerEdges];

    int tid, i, j, killed;
    unsigned int src, des;
    volatile int cnt = 0; //all the nodes stored in the file

    #pragma omp parallel for num_threads(16) private(i,buffer,killed,j,src,des,kk,tid) firstprivate(ReadTime,EdgesInFile)
    for(i = 0;i < ReadTime+1;i++)
        #pragma omp critical
        
            input.read((char*)buffer, sizeof(buffer));
            cout<<"Thread Num:"<<omp_get_thread_num()<<" Read Time:"<<i<<endl;
        
        killed = PerEdges;
        if(i == ReadTime) 
            killed = EdgesInFile - ReadTime*PerEdges; 
        for(j = 0;j < killed;j++) 
            src = (unsigned int)buffer[j];
            des = (unsigned int)buffer[j+1];
            #pragma omp critical
            
            //to store the src and des... 
            
        
    
    cout << "finish the reading!" << endl;
    input.close();


int main()

    clock_t T1 = clock();
    ReadFile(); 
    clock_t T2 = clock();
    cout<< "Reading Time:" << (double)(T2 - T1) / CLOCKS_PER_SEC << "seconds" << endl;
    return 0;

我在代码中读取的文件存储了一个图形,由连续的线组成,每条线(8字节)包括两个连续节点——源节点(4字节)和目标节点(4字节)。节点号存储为无符号整数类型.

但是我不能通过添加#pragma 子句来获得任何加速。阅读时间与OpenMP 无关,也与我在#pragma 子句中设置的num_threads 无关。阅读时间是同样,大约 200 秒。

谁能告诉我问题出在哪里?

【问题讨论】:

如果这是磁盘读取,您的瓶颈将是磁盘读取速度,而不是处理速度,因为看起来您的算法并不糟糕。你能得到实际加载到内存中的时间,而不是总算法吗? 我认为 "ifstream input("./soc-LiveJournal1.bin", ios::in | ios::binary);"该子句一次性将文件从磁盘加载到主存,而我要做的是从不同的内存位置并行读取文件。 不,ifstream 不会提前将整个文件读入内存。通常,只有在您调用read 时才会执行实际读取。在任何地方,您都在关键部分下执行阅读,并且您的并行代码主要由这些部分组成。请注意,只有非关键部分可以使用并行线程加速。 好的。我明白了,谢谢! 【参考方案1】:

在 I/O 操作之前添加 #pragma omp critical 是对的!

然而

omp critical 指令标识了一段代码,必须 一次由一个线程执行。

循环中的大部分代码都在 omp 关键部分。并且您的其余代码不会占用 CPU。

所以你观察到的是正常的。

除非您使用并行文件系统,否则使用 OpenMP 几乎不会提高 I/O 操作的性能。 OpenMP 确实是为了改善 CPU 密集型部分。

【讨论】:

谢谢。但是我认为I/O操作之前的#pragma子句是没有用的...bsc input.read(...)有一个线程保护机制,这使得读操作变得至关重要自然。

以上是关于读取文件时无法使用 OpenMP 获得加速的主要内容,如果未能解决你的问题,请参考以下文章

LMDB数据库加速Pytorch文件读取速度

读取加速度计数据时发现为零

无法使用可读格式的 JavaScript 读取 IndexedDB sqlite 文件

matlab读取任意路径下文件

Java 如何读取目录下的文件内容

如何获得在整个程序执行期间可能创建的最大 OpenMP 线程数?