2013-05-30 92 views
-1

我只花了一段时间试图让这个循环openMPed,但对于2个线程,它使Wall时间翻倍!我错过重要的东西吗?为什么openMP需要这么久?

整体任务是并行读取一个大文件(〜1GB),一个ifstream被分成几个stringbuffer,并且这些用于将数据插入到结构Symbol中。到这里一切都很快。同时赋予循环私有变量str和locVec来进行操作并不会改变某些内容。

vector<string> strbuf; // filled from ifstream 
vector< vector <Symbol> > symVec; // to be filled 


#pragma omp parallel for num_threads(2) default(none) shared(strbuf, symVec) 
for (int i=0; i<2; i++) 
{ 
    string str = strbuf[i]; 
    std::stringstream ss(str); 
    // no problem until here 

    // this is where it slows down: 
    vector<Symbol> locVec; 
    std::copy(std::istream_iterator<Symbol>(ss), std::istream_iterator<Symbol>(), std::back_inserter(locVec)); 


    symVec[i] = locVec; 
} 

编辑:: 对不起,是unprecise,但文件的内容已经被读入sequencially在这一点上分为strbufs。该文件已关闭。在循环内没有文件访问。

回答

1

在一个文件上执行顺序I/O比在文件的不同部分执行I/O要好得多。这基本上归结为导致底层设备上的很多搜索(我在这里假设一个磁盘)。这也增加了将文件读入所述缓冲区所需的底层系统调用的数量。最好使用1个线程按顺序读取文件(可能为mmap()MAP_POPULATE),并将处理分配给不同的线程。

另一种选择是使用诸如aio_read()之类的调用来处理在不同部分中的阅读,如果由于某些原因您不想一次全部阅读文件。

没有所有的代码我不能完全确定,但请记住,简单地打开文件并不能保证它的内容在内存中,并从文件中读取会导致页面错误,然后导致实际的文件内容被读取即使您没有明确地尝试使用读/写操作来读取文件,操作系统也会为您处理。

+0

不好意思,因为文件内容已经按顺序读取了,现在分成了strbufs。该文件已关闭。在循环内没有文件访问。 – niko

+0

@niko为什么还打扰到streambufs?只需找到该文件的结尾,并在此时将其读入一个大缓冲区。它可能更快。复制操作可能会伤害你。 –