Я пишу программу, которая должна запускаться как в серийных, так и в параллельных версиях. Как только я получу его, чтобы сделать то, что он должен делать, я начал пытаться распараллелить его с помощью OpenMP (обязательный).Как оптимально распараллелить вложенные циклы?
Дело в том, что я не могу найти документацию или ссылки о том, когда следует использовать #pragma. Поэтому я стараюсь изо всех сил угадывать и тестировать. Но тестирование не подходит для вложенных циклов.
Как бы вы распараллеливание серии вложенных циклов, как эти:
for(int i = 0; i < 3; ++i){
for(int j = 0; j < HEIGHT; ++j){
for(int k = 0; k < WIDTH; ++k){
switch(i){
case 0:
matrix[j][k].a = matrix[j][k] * someValue1;
break;
case 1:
matrix[j][k].b = matrix[j][k] * someValue2;
break;
case 2:
matrix[j][k].c = matrix[j][k] * someValue3;
break;
}
}
}
}
- высота и ширина, как правило, тот же размер в тестах, которые я должен выполнить. Некоторые примеры тестов - 32x32 и 4096x4096.
- матрица представляет собой массив пользовательских структур с признаками а, б и в
- SomeValue является двойной
Я знаю, что OpenMP не всегда хорошо для вложенных циклов, но любая помощь приветствуется.
[UPDATE]:
До сих пор я пытался разворачивая петли. Это повышает производительность, но могу ли я добавить лишние накладные расходы здесь? Я повторно использую темы? Я попытался получить идентификатор потоков, используемых в каждом, но не понял.
#pragma omp parallel
{
#pragma omp for collapse(2)
for (int j = 0; j < HEIGHT; ++j) {
for (int k = 0; k < WIDTH; ++k) {
//my previous code here
}
}
#pragma omp for collapse(2)
for (int j = 0; j < HEIGHT; ++j) {
for (int k = 0; k < WIDTH; ++k) {
//my previous code here
}
}
#pragma omp for collapse(2)
for (int j = 0; j < HEIGHT; ++j) {
for (int k = 0; k < WIDTH; ++k) {
//my previous code here
}
}
}
[ОБНОВЛЕНИЕ 2]
Помимо разворачивая петли я попытался распараллеливание внешнего цикла (худший прирост производительности, чем разворачивая) и свертывание две внутренние петли (более или менее такой же прирост производительности в качестве разворачивая) , Это время, которое я получаю.
- Серийные: ~ 130 мс
- Loop разворачивая: ~ 49 мс
- Сворачивание две сокровенные петли: ~ 55 мс
- Параллельный внешний цикл: ~ 83 мс
Что вас Думаете, самый безопасный вариант? Я имею в виду, что должно быть в целом лучшим для большинства систем, а не только для моего компьютера?
Извините, что это была опечатка. Исправлено сейчас @HighPerformanceMark – danielsto
Я предполагаю, что 'i' в самом внутреннем цикле является опечаткой для' k'? – Davislor
Да, @ Давислор. Теперь это исправлено. – danielsto