2013-05-30 89 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?只需找到該文件的結尾,並在此時將其讀入一個大緩衝區。它可能更快。複製操作可能會傷害你。 –