2013-11-03 4 views
2

Я работаю над адаптацией программы для использования OpenMP. У меня есть группа вложенных циклов. Самый внешний для цикла - петли оси y, которые спускаются по изображению. Я хотел бы запустить несколько параллельных потоков в цикле, но у меня возникли проблемы с этим.OpenMP For - групповые петли для оптимизации кеша

В настоящее время, когда я бегу 8 потоков он работает как:

thread 0 -> row 0,8,16... 
thread 1 -> row 1,9,17... 
thread 2 -> row 2,10,18... 
thread 3 -> row 3,11,19... 

Я хотел бы, чтобы работать в блоках, так что нить 0 делает первый 1/8 строк. Каков наилучший способ сделать это?

Текущий код:

... 
int y_percent = data_size_Y/8; 
int thread = 0; 

#pragma omp parallel for num_threads(8) firstprivate(vecs, bufferedOut,data_size_X, data_size_Y, kern_cent_X, kern_cent_Y, sum) 
for(int y = y_percent*omp_get_thread_num(); y < (omp_get_thread_num()+1)*y_percent; y++){ // the y coordinate of theoutput location we're focusing on  

ответ

5

Вы можете использовать предложение schedule в инструкции pragma, чтобы указать размер куска, который вы хотите обработать каждый поток. В приведенном ниже примере я указываю метод планирования static с размером chunk, который определяет количество смежных итераций, которые должен получить каждый поток. В этом простом примере каждый поток будет получать куски по 8 итераций каждый (например, поток 0 будет получать итерации 0-7, нить 1 итераций 8-15 и т. Д.). Стоит отметить, что если вас не интересует порядок распределения кусков (например, если вам неважно, получает ли поток 0 первый кусок или нет), вы можете заменить static на dynamic. dynamic дает возможность назначать куски потокам, поскольку они им нужны, вместо того, чтобы предварительно отсылать куски к потокам с самого начала (полезно для балансировки нагрузки, когда некоторые итерации занимают больше времени, чем другие). Для получения более подробной информации о методах планирования, проверьте следующее:

Пример:

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

int main() { 
    int i; 
    int iterations = 32; 
    int num_threads = 4; 

#pragma omp parallel for schedule(static, 8) num_threads(num_threads) 
    for(i=0; i<iterations; i++) { 
    printf("thread %d: %d\n", omp_get_thread_num(), i); 
    } 

} 
+1

Если кто-то не связан с заказом дистрибутива, но он связан с производительностью, то «расписание (динамический)» следует использовать только в качестве последнего средства для устранения дисбаланса нагрузки. Накладные расходы на динамическое планирование огромны по сравнению со статическим. –

1

Вы могли бы просто использовать следующий код для достижения этой цели.

#pragma omp parallel for num_threads(8) 
for(int y = 0; y < data_size_Y; y++) { 
    .... 
} 

Вообще-то я думаю, что длинный список firstprivate не является необходимым. В зависимости от того, как именно вы используете эти переменные, большинство из них должно быть определено как shared.

+2

Downvoter, уход объяснить свой голос? –

+0

Я не спускал вниз, но предположительно, что для констант хорошей практикой является использование firstprivates вместо общего. по моему опыту, на самом деле гораздо быстрее использовать firstprivate. – Julius

Смежные вопросы