openMP Как получить лучший рабочий баланс? - PullRequest
2 голосов
/ 30 октября 2011

Я работаю над программой, которая должна вычислить foobar для многих файлов, foobar может быть выполнена параллельно или последовательно для одного файла, программа получит много файлов (, который может иметь различный размер! ) и применять вычисления foobar параллельно или последовательно к каждому из них с указанным числом потоков.

Вот как запускается программа на 8 файлах с тремя потоками.

./program 3 file1 file2 file3 file4 file5 file6 file7 file8

Планирование по умолчанию, которое я реализовал, заключается в параллельном воздействии на один поток в каждом файле для выполнения вычислений (так теперь работает моя программа!).

Редакция: вот расписание по умолчанию, которое я использую

#pragma omp parallel for private(i) schedule(guided,1)
for (i = 0; i < nbre_file; i++)
   foobar(files[i]);  // according to the size of files(i) foobar can react as a sequential or a parallel program (which could induce nested loops)

См. Изображение ниже

Default scheduling

На изображении выше последнее время - это время, затрачиваемое на последовательное решение foobar для самого большого файла file8 .

Я думаю, что лучшее планирование, которое будет эффективно работать с рабочим балансом, могло бы заключаться в применении вычисления foobar для большого файла параллельно. Как на рисунке ниже, где tr i представляет поток.

enter image description here

таким образом, что в последний раз будет потрачено время на решение foobar параллельно ( на изображении выше мы использовали два потока! ) для самого большого файла file8

Мой вопрос:

можно ли сделать такое планирование с помощью openmp?

Спасибо за любой ответ!

1 Ответ

1 голос
/ 31 октября 2011

Вы пробовали dynamic планирование вместо руководства?

Если обычные пункты планирования не сработали, вы можете попытаться выполнить распараллеливание цикла вручную и вручную назначить файлы определенным потокам. Итак, ваш цикл будет выглядеть так:

#pragma omp parallel
{
   id = omp_get_thread_num();
   if(id==0){ //thread 0
       for (i = 0; i < nbre_of_small_files; i++)
           foobar(files[i]); 
    }
    else { //thread 1 and 2 
       for (j = 0; j < nbre_of_big_files; j=j+2)
           if(id==1){//thread 1
               foobar(files[j]);
            } 
            else{ //thread 2
               foobar(files[j+1]); 
            }
    }

}

Здесь нить 0 делает все маленькие файлы. Второй и третий поток делают большие файлы.

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