2011-05-16 32 views
-1

我將幾個線程收到的處理結果相結合時遇到了一些問題。我不確定,如果我正確使用openmp。下面的代碼提取顯示了我的代碼的openmp部分。將線程結果與openmp結合起來

參數:

線程私有:

它:地圖迭代器(時間戳,用戶鑰)

伊特: map迭代((時間戳,用戶鑰)/ INT量)

thread_result_map: typedef map < userkey(str),timestamp(str)>

的情況下,誰:

日誌: char數組
尺寸: log.size()
標識符匹配正則表達式(時間戳,用戶鑰)

線程之間共享,時間戳,用戶密鑰: boost ::正則表達式
combined_result_map:的typedef地圖< thread_result_map,命中(INT)>

#pragma omp parallel shared(log, size, identifier, timestamp, userkey) private(it, ite, str_time, str_key, vec_str_result, i, id, str_current, when, who, thread_result_map) 
    { 
#pragma omp for 
    for (i = 0 ; i < size ; i++){ 
      str_current.push_back(log[i]); 
     if (log[i] == '\n') { 
      if (boost::regex_search(str_current, identifier)){ 
       boost::regex_search(str_current, when, timestamp); 
       str_time = when[0]; 
       boost::regex_search(str_current, who, userkey); 
       str_key = who[0]; 
       thread_result_map.insert(make_pair(str_time, str_key)); 
       } 
       str_current = ""; //reset temp string 
      } 
     } 
#pragma omp critical 
     { 
     for (it=thread_result_map.begin(); it!=thread_result_map.end(); it++) { 
       id = omp_get_thread_num(); 
      cout << thread_result_map[it->first] << 
          thread_result_map[it->second]; 
      cout << "tID_" << id << " reducing" << endl; 
      } 
     } 
    } 

正如你可以看到每個線程都有自己的字符數組的分區,通過線從陣列分析線,如果當前字符串被認定「標識符「,時間戳和用戶密鑰被添加到線程的私有結果映射(字符串/字符串)。

現在循環後,我有幾個線程的私人結果地圖。 combined_result_map是地圖內的地圖。關鍵是線程結果的鍵/值的組合,值是該組合的出現次數。

我只解析時間戳的一部分,所以當在1小時內出現多次相同的用戶密鑰時,計數器將增加。

結果應該是這個樣子:

TIME(MMM/DD/HH/);USERKEY;HITS 
May/25/13;SOMEKEY124345;3 

所以我沒有問題的關鍵部分結合擊量(我已刪除)通過指定組合+ =結果。

但是我怎樣才能以相同的方式結合我的結果地圖?我知道我必須遍歷線程映射,但是當我在循環內部放置一個「cout」來測試每個線程時,它只會調用一次。

在我的本地syslog測試運行給我下面的輸出當我設置的所有正則表達式「錯誤」(以確保每個標識線將有一個用戶鑰,並與同名的時間戳):

模式解析訪問串:

error Pattern for parsing Timestamp: 
error Pattern for parsing Userkey: 
error 

*** Parsing File /var/log/syslog 

errortID_0 reducing errortID_1 
reducing errortID_2 reducing 
errortID_3 reducing 

*** Ok! ________________ hits : 
418 worktime: 0.0253871s 

(計算點擊來自線程專用櫃檯,我在代碼中刪除以上)

因此,我的每個線程都會執行一個cout並離開循環,儘管所有在一起的應該有418個命中。那麼我做錯了什麼?如何從我的openmp區域內迭代我的結果?

回答

0

自己發現了這個問題,對於提出愚蠢的問題感到抱歉。

我試圖多次添加相同的密鑰,這就是爲什麼地圖大小沒有增加,每個線程只循環一次。

編輯:

如果有人有興趣的解決方案如何線程的結果結合起來,這是我做到了。也許你會看到任何可以改進的東西。

我剛剛將本地線程結果圖更改爲pairs(str,str)的矢量。

這是完整的工作openmp代碼部分。也許它對任何人都有用:

#pragma omp parallel shared(log, size, identifier, timestamp, userkey) private(it, ite, str_time, str_key, i, id, str_current, when, who, local_res) 
    { 
#pragma omp for 
     for (i = 0 ; i < size ; i++){ 

      str_current.push_back(log[i]); 

      if (log[i] == '\n') { // if char is newline character 
       if (boost::regex_search(str_current, identifier)){ // if current line is access string 
        boost::regex_search(str_current, when, timestamp); // get timestamp from string 
        str_time = when[0]; 
        boost::regex_search(str_current, who, userkey); // get userkey from string 
        str_key = who[0]; 
        local_res.push_back((make_pair(str_time, str_key))); // append key-value-pair(timestamp/userkey) 
        id = omp_get_thread_num(); 
        //cout << "tID_" << id << " - adding pair - my local result map size is now: " << local_res.size() << endl; 
       } 
       str_current = ""; 
      } 
     } 

#pragma omp critical 
     { 
      id = omp_get_thread_num(); 
      hits += local_res.size(); 
      cout << "tID_" << id << " had HITS: " << local_res.size() << endl; 
      for (i = 0; i < local_res.size(); i++) { 
       acc_key = local_res[i].second; 
       acc_time = local_res[i].first; 
       if(m_KeyDatesHits.count(acc_key) == 0) { // if there are no items for this key yet, make a new entry 
        m_KeyDatesHits.insert(make_pair(acc_key, str_int_MapType())); 
       } 
       if (m_KeyDatesHits[acc_key].count(acc_time) == 0) { // "acc_time" is a key value, if it doesn't exist yet, add it and set "1" as value 
        m_KeyDatesHits[acc_key].insert(make_pair(acc_time, 1)); 
        it = m_KeyDatesHits.begin(); // iterator for userkeys/maps 
        ite = m_KeyDatesHits[acc_key].begin(); // iterator for times/clicks 
       } else m_KeyDatesHits[acc_key][acc_time]++; // if userkey already exist and timestamp already exists, count hits +1 for it 

      } 
     } 
    } 

我做了一些測試,它確實運行得很快。

使用4個線程可以搜索150MB的LogFile進行訪問事件,解析每個事件的自定義用戶密鑰和日期,並將結果在4秒內結合起來。

在最後它創建一個導出列表。這是程序輸出:

HELLO,歡迎來到LogMap 0.1!

C++/OpenMP的存儲器映射解析引擎
_ __ _ __ _ __ _ __ _ __ _ __可用處理器= 4
線程數的數= 4

解析訪問字符串的模式:
GET/_openbooknow /鍵/模式的
解析時間戳:\ d {2}/\ W {3}/\ d {4}
模式解析USERKEY:
[A-ZA-Z0-9] { 20,32}

*解析文件
/home/c0d31n/Desktop/access_log-test.txt

HITS:169147 HITS:169146 HITS:169146
HITS:169147

*好的! _ __ _ ____點擊:
676586工作時間:4.03816s

*新導出文件創建 「./test.csv」

根@ c0d3b0x:〜/工作區/ OpenBookMap/Release#
貓測試。CSV
「1nDh0gV6eE3MzK0517aE6VIU0」; 「28/MAR/2011」, 「18813」
「215VIU1wBN2O2Fmd63MVmv6QTZy」; 「28/MAR/2011」, 「6272」
「36Pu0A2Wly3uYeIPZ4YPAuBy」; 「18 /月/ 2011」;」 18816"
「36Pu0A2Wly3uYeIPZ4YPAuBy」; 「21 /月/ 2011」, 「12544」
「36Pu0A2Wly3uYeIPZ4YPAuBy」; 「22/MAR/2011」, 「12544」
「36Pu0A2Wly3uYeIPZ4YPAuBy」; 「23 /月/ 2011」; 「18816」
「9E1608JFGk2GZQ4ppe1Grtv2」; 「28/MAR/2011」, 「12544」
「pachCsiog05bpK0kDA3K2lhEY」; 「17 /月/ 2011」, 「18029」
「pachCsiog05bpK0kDA3K2lhEY」; 「18 /月/ 2011」 ;「12544」
「pachCsiog05bpK0kDA3K2lhEY」; 「21 /月/ 2011」, 「18816」
「pachCsiog05bpK0kDA3K2lhEY」; 「22/MAR/2011」, 「6272」
「pachCsiog05bpK0kDA3K2lhEY」; 「23 /月/ 2011」,「18816 「
」pachCsiog05bpK0kDA3K2lhEY「;」 28/MAR/2011 「」 501760"
「1nDh0gV6eE3MzK0517aE6VIU0」; 「28/MAR/2011」, 「18813」
「215VIU1wBN2O2Fmd63MVmv6QTZy」; 「28/MAR/2011」;」 6272"
「36Pu0A2Wly3uYeIPZ4YPAuBy」; 「18 /月/ 2011」, 「18816」
「36Pu0A2Wly3uYeIPZ4YPAuBy」; 「21 /月/ 2011」, 「12544」
「36Pu0A2Wly3uYeIPZ4YPAuBy」; 「22/MAR/2011」; 「12544」
「36Pu0A2Wly3uYeIPZ4YPAuBy」; 「23 /月/ 2011」, 「18816」
「9E1608JFGk2GZQ4ppe1Grtv2」; 「28/MAR/2011」, 「12544」
「pachCsiog05bpK0kDA3K2lhEY」; 「17 /月/ 2011」,「18029 「
」pachCsiog05bpK0kDA3K2lhEY「;」 18 /月/ 2011 「」 12544"
「pachCsiog05bpK0kDA3K2lhEY」; 「21 /月/ 2011」, 「18816」
「pachCsiog05bpK0kDA3K2lhEY」; 「22/MAR/2011」;」 6272"
「pachCsiog05bpK0kDA3K2lhEY」; 「23 /月/ 2011」, 「18816」
「pachCsiog05bpK0kDA3K2lhEY」; 「28/MAR/2011」, 「501760」