Как распараллелить для цикла внутри другого для цикла с OpenMP - PullRequest
0 голосов
/ 08 ноября 2018

Я хочу получить лучшую производительность, распараллеливая эти циклы:

// EXAMPLE
for (;;) {
    // DO SOMETHING
    for(;;) {
        // DO SOMETHING
    }
}

Я знаю три способа распараллеливания о примере:

// EXAMPLE - FIRST LOOP PARALLEL
#pragma omp parallel for
for (;;) {
    // DO SOMETHING
    for(;;) {
        // DO SOMETHING
    }
}

// EXAMPLE - FIRST AND SECOND LOOP PARALLEL NO NESTED
omp_set_nested(0); // default option
#pragma omp parallel for
for (;;) {
    // DO SOMETHING
    #pragma omp parallel for
    for(;;) {
        // DO SOMETHING
    }
}

// EXAMPLE - FIRST AND SECOND LOOP PARALLEL NESTED
omp_set_nested(1);
#pragma omp parallel for
for (;;) {
    // DO SOMETHING
    #pragma omp parallel for
    for(;;) {
        // DO SOMETHING
    }
}

Какой лучший способ сделать это? Или в каких ситуациях я должен использовать один или другой?

Спасибо.

1 Ответ

0 голосов
/ 08 ноября 2018

Один уровень распараллеливания почти всегда лучший, т. Е. Пример 1: первый параллельный цикл.

Пример 2 фактически будет делать то же, что и пример 1 (второй оператор #pragma omp parallel for игнорируется, поскольку вложенное распараллеливание отключено).

Пример 3, скорее всего, плохая идея. Затраты на порождение новых потоков возникают на каждой итерации из цикла 1. Случаи, когда было бы лучше распараллеливать только первый цикл (или только второй цикл), нетривиальны. Не гарантируется, что он будет поддерживаться всеми компиляторами (некоторые могут игнорировать вложенную часть).

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

// EXAMPLE - SECOND LOOP PARALLEL
#pragma omp parallel
for (;;) {
    // DO SOMETHING EVERY THREAD SHOULD DO
    // e.g. declare local variables, increment private counter...
    #pragma omp single
    {
    // DO SOMETHING ONCE ONLY
    // e.g. read data from a file, initialize a shared variable
    }
    #pragma omp for
    for(;;) {
        // DO SOMETHING
    }
}
...