Распараллеливание цикла с openMP внутри цикла while? - PullRequest
0 голосов
/ 07 января 2019

У меня есть структура программы, подобная этой:

ssize_t remain = nsamp;
while (!nsamp || remain > 0) { 
    #pragma omp parallel for num_threads(nthread)  
    for (ssize_t ii=0; ii < nthread; ii++) {
        <generate noise>       
    } 

    // write noise
    out.write(data, nthread*PERITER);
    remain -= nthread*PERITER;
 }

Проблема в том, что, когда я проверяю результат этого, если я запускаю, например, с двумя потоками, иногда это занимает ~ то же время, что и один поток, а иногда я получаю ускорение в 2 раза, такое ощущение, что есть какой-то состояния гонки синхронизации, с которым я сталкиваюсь, иногда я сталкиваюсь с этим, и все идет гладко, а иногда (часто) нет.

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

Edit: используя strace, я вижу lot вызовов sched_yield (). Вероятно, это заставляет меня выглядеть так, будто я много работаю с процессором, но я борюсь с планировщиком за хорошую шаблон планирования.

Ответы [ 2 ]

0 голосов
/ 07 января 2019

Я бы предложил что-то вроде этого. Для nsamp == 0 вам понадобится более разумная обработка. Для правильной обработки сигналов с помощью OpenMP, пожалуйста, обратитесь к этому ответу .

ssize_t remain = nsamp;
#pragma omp parallel num_threads(nthread) shared(out, remain, data)
while (remain > 0) { 
    #pragma omp for
    for (ssize_t ii=0; ii < nthread; ii++) {
        /* generate noise */
    }
    #pragma omp single
    {
        // write noise
        out.write(data, nthread*PERITER);
        remain -= nthread*PERITER;
    }
}
0 голосов
/ 07 января 2019

Вы создаете новую связку потоков каждый раз, когда вводится цикл while. После параллельного цикла потоки уничтожаются. Из-за природы цикла while это может происходить нерегулярно (в зависимости от условия). Поэтому, если ваши циклы выполняются всего несколько раз, тогда процесс создания потока может перевесить реальную рабочую нагрузку, и, таким образом, вы получите максимально последовательную производительность, если не меньше. Однако, возможно, параллельная система (OpenMP) может обнаружить, многократно ли вводится цикл, чтобы поддерживать потоки.

Ничего не гарантируется, хотя.

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