Объединить результаты темы с openmp - PullRequest
0 голосов
/ 16 мая 2011

У меня проблемы с объединением результатов обработки, полученных из нескольких потоков. И я не уверен, правильно ли я использую openmp. В приведенном ниже фрагменте кода показана часть моего кода openmp.

Параметры:

Тема приватная:

it: итератор карты (временная метка, userkey)

ite: итератор карты ((отметка времени, userkey) / int amount)

thread_result_map: typedef map

когда, кто: соответствующее регулярное выражение (временная метка, ключ пользователя)

делится между потоками:

log: массив символов
размер: log.size ()
идентификатор, метка времени, ключ пользователя: boost :: regex pattern
комбинированный_результат_карты: карта определения типа

#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;
            }
        }
    }

Как вы можете видеть, каждый поток имеет свой собственный раздел массива char, он анализирует строку за строкой из массива, и если текущая строка идентифицируется по «идентификатору», отметка времени и ключ пользователя добавляются в частную карту результатов потока (строка / строка).

Теперь после цикла у меня есть несколько частных карт результатов потока. Combined_result_map - это карта внутри карты. Ключ - это комбинация ключ / значение результата потоков, а значение - это количество вхождений этой комбинации.

Я анализирую только часть метки времени, поэтому, когда через 1 час один и тот же пользовательский ключ появляется несколько раз, счетчик посещений будет увеличен.

Результат должен выглядеть примерно так:

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

Таким образом, у меня нет проблем с комбинированием количества попаданий в критическом разделе (который я удалил) путем указания комбинированных + = результатов.

Но как я могу комбинировать свои карты результатов одинаково? Я знаю, что должен перебирать карты потоков, но когда я помещаю «cout» в цикл для тестирования, каждый поток вызывает его только один раз.

Тестовый запуск моего локального системного журнала дает мне следующий вывод, когда я устанавливаю для всех регулярных выражений значение «error» (чтобы убедиться, что каждая идентифицированная строка будет иметь userkey и временную метку с тем же именем):

Шаблон для разбора строки доступа:

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

(Рассчитанные хиты получены из частных счетчиков потоков, которые я удалил в приведенном выше коде)

Таким образом, каждый из моих 4-х потоков выполняет один бросок и выходит из цикла, хотя все вместе должно иметь 418 попаданий. Так что я делаю не так? Как мне перебрать результаты из моей открытой области?

1 Ответ

0 голосов
/ 17 мая 2011

Сам нашел проблему, извините за глупые вопросы.

Я пытался добавить один и тот же ключ несколько раз, поэтому размер карты не увеличился, и каждый поток зацикливался только один раз.

Edit:

Если кто-то заинтересован в решении, как объединить результаты потоков, я так и сделал. возможно, вы видите все, что можно улучшить.

Я только что изменил карту результатов локальных потоков на вектор 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 события доступа, анализирует пользовательский ключ и дату каждого события и объединяет результаты менее чем за 4 секунды.

В конце создает список экспорта. Это вывод программы:

ПРИВЕТ, добро пожаловать в 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

Хитов: 169147 Хитов: 169146 Хитов: 169146
Хиты: 169147

* Хорошо! _ __ _ ____ хитов:
676586 рабочее время: 4,03816 с

* создан новый файл экспорта: "./test.csv"

корень @ c0d3b0x: ~ / рабочее пространство / OpenBookMap / Release #
cat test.csv
"1nDh0gV6eE3MzK0517aE6VIU0"; "28 / Mar / 2011", "18813"
"215VIU1wBN2O2Fmd63MVmv6QTZy"; "28 / Mar / 2011", "6272"
"36Pu0A2Wly3uYeIPZ4YPAuBy"; "18 / Mar / 2011", "18816"
"36Pu0A2Wly3uYeIPZ4YPAuBy"; "21 / Mar / 2011", "12544"
"36Pu0A2Wly3uYeIPZ4YPAuBy"; "22 / Mar / 2011", "12544"
"36Pu0A2Wly3uYeIPZ4YPAuBy"; "23 / Mar / 2011", "18816"
"9E1608JFGk2GZQ4ppe1Grtv2"; "28 / Mar / 2011", "12544"
"PachCsiog05bpK0kDA3K2lhEY"; "17 / Mar / 2011", "18029"
"PachCsiog05bpK0kDA3K2lhEY"; "18 / Mar / 2011", "12544"
"PachCsiog05bpK0kDA3K2lhEY"; "21 / Mar / 2011", "18816"
"PachCsiog05bpK0kDA3K2lhEY"; "22 / Mar / 2011", "6272"
"PachCsiog05bpK0kDA3K2lhEY"; "23 / Mar / 2011", "18816"
"PachCsiog05bpK0kDA3K2lhEY"; "28 / Mar / 2011", "501760"
"1nDh0gV6eE3MzK0517aE6VIU0"; "28 / Mar / 2011", "18813"
"215VIU1wBN2O2Fmd63MVmv6QTZy"; "28 / Mar / 2011", "6272"
"36Pu0A2Wly3uYeIPZ4YPAuBy"; "18 / Mar / 2011", "18816"
"36Pu0A2Wly3uYeIPZ4YPAuBy"; "21 / Mar / 2011", "12544"
"36Pu0A2Wly3uYeIPZ4YPAuBy"; "22 / Mar / 2011", "12544"
"36Pu0A2Wly3uYeIPZ4YPAuBy"; "23 / Mar / 2011", "18816"
"9E1608JFGk2GZQ4ppe1Grtv2"; "28 / Mar / 2011", "12544"
"PachCsiog05bpK0kDA3K2lhEY"; "17 / Mar / 2011", "18029"
"PachCsiog05bpK0kDA3K2lhEY"; "18 / Mar / 2011", "12544"
"PachCsiog05bpK0kDA3K2lhEY"; "21 / Mar / 2011", "18816"
"PachCsiog05bpK0kDA3K2lhEY"; "22 / Mar / 2011", "6272"
"PachCsiog05bpK0kDA3K2lhEY"; "23 / Mar / 2011", "18816"
"pachCsiog05bpK0kDA3K2lhEY"; "28 марта 2011 г."; "501760"

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...