Использование различных потоков в OMP для вложенных циклов - PullRequest
0 голосов
/ 08 февраля 2020

Перед тем, как начать, я должен упомянуть, что циклы в моем исходном коде не являются идеально вложенными, поэтому я не могу использовать примитив "схлопывание".

Я пытаюсь нарезать как внешний, так и внутренний цикл for в следующем коде. Пример ниже работает нормально, однако, есть проблема! Внутренний l oop использует те же идентификаторы потоков, что и внешний, что приводит к снижению производительности. Мой компьютер имеет 20 потоков, и я хочу, чтобы те, которые простаивали, использовались во внутренней l oop. До сих пор я не мог найти решение. Любое предложение?

Вывод примера кода выглядит следующим образом:

iter (0, 0), tid external l oop: 0, tid inner l oop: 0

iter (0, 1), тид внешний l oop: 0, тид внутренний l oop: 0

iter (0, 6), тид внешний l oop: 0, внутренний тид l oop: 0

iter (1, 0), внешний тид l oop: 1, внутренний tid l oop: 0

iter (1, 1) , внешняя сторона t * l oop: 1, внутренняя часть tid l oop: 0

iter (1, 6), внешняя сторона t l oop: 1, внутренняя часть tid l oop: 0

iter (1, 4), внешний тид l oop: 1, внутренний тид l oop: 2

iter (1, 5), внешний тид l oop: 1, внутренняя часть l oop: 2

iter (1, 2), внешняя часть l oop: 1, внутренняя часть l oop: 1

iter (1, 3) , внешняя сторона l oop: 1, внутренняя часть t * l8210: 1

iter (0, 4), внешняя сторона l oop: 0, внутренняя часть l oop: 2

iter (0, 5), tid external l oop: 0, tid inner l oop: 2

iter (0, 2), tid external l oop: 0, внутренняя часть l oop: 1

iter (0, 3), внешняя часть l oop: 0, т внутренний идентификатор l oop: 1

iter (2, 0), внешний тид l oop: 2, внутренний tid l oop: 0

iter (3, 4) , внешняя сторона l oop: 0, внутренняя часть l oop: 2

iter (2, 1), внешняя сторона l oop: 2, внутренняя часть t * oop: 0

iter (3, 5), внешняя часть l oop: 0, внутренняя часть l oop: 2

iter (4, 2), внешняя часть t * oop: 1, внутренний тид l oop: 1

iter (3, 0), внешний тид l oop: 0, внутренний tid l oop: 0

iter (3, 2) , внешняя сторона t * l oop: 0, внутренняя часть tid l oop: 1

iter (4, 4), внешняя сторона t l oop: 1, внутренняя часть tid l oop: 2

iter (2, 6), внешняя часть l oop: 2, внутренняя часть l oop: 0

iter (4, 5), внешняя часть t * oop: 1, внутренний тид l oop: 2

iter (2, 2), внешний тид l oop: 2, внутренний тид l oop: 1

iter (3, 3) , tid external l oop: 0, tid inner l oop: 1

и т. д.

#include <stdio.h>
#include <omp.h>

int main (void)
{
  int i,j,thid;
  omp_set_nested(1);

    #pragma omp parallel for default(none) num_threads(3) private(i,j,thid)  schedule(static,1) 
    for (i = 0; i < 8; i++){
        thid = omp_get_thread_num();
        #pragma omp parallel for num_threads(3) schedule(static,2)
        for (j = 0; j < 7; j++)
        printf("iter (%0d, %0d), tid outer loop: %0d, tid inner loop: %0d\n", i, j, thid, omp_get_ancestor_thread_num(omp_get_level()) );
    }


  return 0;
}

1 Ответ

0 голосов
/ 13 февраля 2020

ваш код в порядке, но вы должны установить num_threads только один раз. Если ваш компьютер поддерживает 20 потоков, установите num_threads равным 16

#pragma omp parallel for default(none) num_threads(16) private(i,j,thid)  schedule(static,1) 
for (i = 0; i < 8; i++){
    thid = omp_get_thread_num();
    //remove num_threads here
    #pragma omp parallel for schedule(static,2)
    for (j = 0; j < 7; j++)
    printf("iter (%0d, %0d), tid outer loop: %0d, tid inner loop: %0d\n", i, j, thid, omp_get_ancestor_thread_num(omp_get_level()) );
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...