сокращение с типом строки в OpenMP - PullRequest
0 голосов
/ 16 декабря 2018

Я использую OpenMP, чтобы парализовать цикл for следующим образом:

std::stringType = "somevalue";
#pragma omp parallel for reduction(+ : stringType)
//a for loop here which every loop appends a string to stringType

Единственный способ, которым я могу думать, - это сначала преобразовать в представление int каким-то образом, а затем преобразовать обратно в концено это имеет очевидные накладные расходы.Есть ли лучшие способы выполнить этот стиль работы?

1 Ответ

0 голосов
/ 17 декабря 2018

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

Нет гарантии, что цикл OpenMP for будет распределять непрерывные итерации для каждого потокаесли расписание цикла явно не запрашивает это.Также нет гарантии, что непрерывные блоки будут распределены путем увеличения номера потока (т. Е. Поток № 0 может пройти итерации 1000–1999, а поток № 1 - 0–999).Если вам нужно такое поведение, вы должны определить свое собственное расписание.

Что-то вроде:

int N=1000;
std::string globalString("initial value");

#pragma omp parallel shared(N,stringType)
{
    std::string localString; //Empty string

    // Set schedule
    int iterTo, iterFrom;
    iterFrom = omp_get_thread_num() * (N / omp_get_num_threads());
    if (omp_get_num_threads() == omp_get_thread_num()+1)
        iterTo =  N;
    else
        iterTo = (1+omp_get_thread_num()) * (N / omp_get_num_threads());

    // Loop - concatenate a number of neighboring values in the right order
    // No #pragma omp for: each thread goes through the loop, but loop
    // boundaries change according to the thread ID
    for (int ii=iterTo; ii<iterTo ; ii++){
        localString += get_some_string(ii);
    }

    // Dirty trick to concatenate strings from all threads in the good order
    for (int ii=0;ii<omp_get_num_threads();ii++){
        #pragma omp barrier
        if (ii==omp_get_thread_num())
            globalString += localString;
    }

}

Лучшим способом было бы иметь общий массив std::string, каждый поток используетодин как местный аккумулятор.В конце один поток может выполнить конкатенационную часть (и избежать подвоха и всех его чрезмерных вызовов barrier).

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