2015-12-30 129 views
0

我正在實施一個map/reduce並行項目。然而,使用一個輸入文件(或多或少)1GB,對於一個字數玩具的例子,只有一個映射器(它映射整個文件),我收到一個std::bad_alloc異常。不幸的是,這隻發生在遠程Xeon Phi(更小的RAM)上,所以沒有深度調試。爲什麼std :: bad_alloc被拋出?

然而,內存資源佔用2個地方:當映射器讀取(存儲)在整個文件中的char *

void getNextKeyValue() { 
    key = pos;//int 
    value = new char[file_size];//file_size only with 1 mapper 
    ssize_t result = pread(fd, value, file_size, pos); 
    assert(result == (file_size)); 
    morePairs = false; 
} 

而另外一個當map函數被調用等一系列pair<char*,int>存儲在內部vector作爲地圖的結果:

地圖功能:

std::function<void(int key, char *value,MapResult<int,char*,char*,int> *result)> map_func = [](int key,char *value,MapResult<int,char*,char*,int> *result) { 
    const char delimit[]=" \t\r\n\v\f"; 
    char *token , *save; 
    token = strtok_r(value, delimit, &save); 
    while (token != NULL){ 
     result->emit(token,1); 
     token = strtok_r (NULL,delimit, &save); 
    } 
}; 

emit實現(圖結果代):

void emit(char* key, int value) { 
     res.push_back(pair<char*,int>(key,value)); 
    } 
    ... 
    private: 
    vector<pair<char*,int>> res; 

注:通常emitkeyvalue是基於模板的,但我忽略了他們在這個例子中claricity。

在我認爲std::bad_alloc是由於char *value(這需要1GB)拋出的第一位置,但異常被測試cout消息放置在value分配之後(因此that'not問題)後拋出。

從我讀到的關於strtok的實現中,原始的char*被修改(在每個令牌的末尾添加\0),所以沒有增加內存分配。

唯一剩下的可能性是vector<pair<char*,int>>佔用的空間,但我無法計算其空間(請幫助我)。假設平均字長爲5個字,我們應該有〜2 * 10^8個字。

更新後1201ProgramAlarm's answer 不幸的是,預先計算單詞的數量,然後調用resize()以消除未使用的矢量的內存是不可行的,原因有二:

  1. 這將大大降低性能。在不調用emit的情況下,只計算280MB的文件的字數,在1329ms的總時間執行時間內(在第一次讀取文件時約爲5000s),需要1242ms。
  2. 使用此解決方案時,最終用戶應該在編寫map函數時深入考慮內存使用情況,這通常不會發生在像Hadoop這樣的經典地圖/縮減框架中。
+0

您是否嘗試使用調試器來查看引發異常的位置? –

+0

正如我在問題中所說的那樣,由於我在遠程Xeon Phi上啓動了該程序,因此無法進行調試。 – justHelloWorld

回答

0

問題不是vector所用的空間,它是容量較小時以前由矢量使用的所有空間。除非您在向量上調用reserve,否則當您推入第一個元素時,它將開始爲空,並分配少量空間(對於一個元素通常足夠大)。在稍後的推送中,如果沒有足夠的剩餘空間分配,它將分配更多(1.5倍或2倍的當前大小)。這意味着你需要足夠的空閒內存來用於較小的尺寸和較大的內存。因爲釋放的內存塊在組合時仍然不足以滿足下一個較大的請求量,則可能會有很多免費但未使用的內存。

您應該致電res.reserve(/*appropriate large size*/),或將容器切換爲deque,儘管最終需要更多空間,但在增長時不需要進行重新分配。爲了保留大小,您可以走一遍文件,查看其中有多少單詞,爲它們預留空間,然後再次行走並保存單詞。

+0

回答了更新問題 – justHelloWorld

相關問題