Member 14361566 Ответов: 3

Openmp для сокращения времени выполнения


Привет.

Я пытаюсь оптимизировать это кодирование с помощью OpenMP, чтобы сократить время выполнения. Тем не менее, я попытался добавить #pragma omp parallel в цикл for, но время выполнения больше. Как оптимизировать этот код с помощью OpenMP?

Что я уже пробовал:

#include <stdio.h>
#include <omp.h>
 
int main()
{
 int array[10][10], row, column, i, j, sum = 0;
 printf("\nEnter The Limit of Rows:\t");
 scanf("%d", &row);
 printf("\nEnter The Limit of Columns:\t");
 scanf("%d", &column);
 printf("\nEnter Elements in the %d*%d Matrix\n", row, column);

 for(j = 0; j < column; j++)
 {
     for(i = 0; i < row; i++)
     {
         scanf("%d", &array[i][j]);
     }
 }
 printf("\nArray\n");
 for(j = 0; j < column; j++)
 {
     for(i = 0; i < row; i++)
     {
         printf("%4d", array[i][j]);
     }
     printf("\n");
 }

 for(i = 0; i < row; i++)
 {
     for(j = 0; j < column; j++)
     {
         sum = sum + array[i][j];
     }
     printf("\nSum of Column No. [%d]:\t%d", i, sum);
     sum = 0;
 }
 printf("\n");
 return 0;
}

3 Ответов

Рейтинг:
2

Patrice T

Цитата:
Я пытаюсь оптимизировать это кодирование с помощью OpenMP, чтобы сократить время выполнения. Тем не менее, я попытался добавить #pragma omp parallel в цикл for, но время выполнения больше. Как оптимизировать этот код с помощью OpenMP?

Ваша проблема заключается в том, что MP приходит по себестоимости, это означает, что установка потоков и сбор результатов стоят времени. Таким образом, каждая нить должна сделать достаточно работы, чтобы она стоила своих затрат.
Хороший стиль кодирования также может помочь ускорить потоки.
Например:
В этом коде, sum исходит из другой части кода, Вы должны ретранслировать на самом деле, что переменная, если она не используется для другой задачи, чтобы получить правильный результат.
for(i = 0; i < row; i++)
{
    for(j = 0; j < column; j++)
    {
        sum = sum + array[i][j];
    }
    printf("\nSum of Column No. [%d]:\t%d", i, sum);
    sum = 0;
}

Здесь sum не могу ошибиться в другом промежуточном использовании.
for(i = 0; i < row; i++)
{
    sum = 0;
    for(j = 0; j < column; j++)
    {
        sum = sum + array[i][j];
    }
    printf("\nSum of Column No. [%d]:\t%d", i, sum);
}

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

Другая проблема:
Вы еще не протестировали свой код
с матрицами
1 2
3 4
вы получаете
3 7
когда вы ожидаете
4 6
потому что ваш код суммирует строки вместо столбцов.


Рейтинг:
1

Stefan_Lang

Если вы хотите сократить время выполнения, избавьтесь от ввода-вывода в коде, который вы хотите оптимизировать! Ввод-вывод не может быть распараллелен осмысленным образом. Кроме того, обработка каждого отдельного оператора printf и scanf займет гораздо больше времени, чем все суммирование по массиву 10*10. Вы не можете сделать значимое измерение производительности ваших программ, пока у вас есть ввод-вывод, а фактическая обработка настолько тривиальна. Попробуйте измерить время вашего кода, когда вы удаляете суммирование: держу пари, вам будет трудно увидеть разницу.

Прочтите Решение 1 для получения дальнейших советов. Рик прав: распараллеливание кода добавляет сложности коду, и если происходит недостаточно обработки, на которую вы можете сэкономить время, выполнение займет больше, а не меньше времени.


Рейтинг:
0

Rick York

Трудно расшифровать, что происходит с этим, потому что он потерял свой отступ.

Из того, что я могу сказать, этот код не будет легко распараллеливаться, потому что он настолько тривиален, что время, затрачиваемое на синхронизацию, будет перегружать вычисления. В этом коде OpenMP должен был бы использовать блокировку переменной sum, и это будет очень неэффективно.

Лучшим подходом было бы иметь промежуточную сумму для каждой строки, а затем суммировать их все. Сумма для каждой строки может быть выполнена параллельно, потому что они независимы. Вы можете сохранить данные в массиве с одним слотом на строку, и тогда синхронизация не потребуется. Затем сумма строк может быть получена с помощью стандартного сокращения. Они распространены в мире CUDA, но я не знаю, есть ли они в OpenMP. Если сокращение недоступно в OpenMP, то можно выполнить стандартный линейный расчет.


Stefan_Lang

Я исправил форматирование кода. Не то чтобы это помогло ;-)

5ed