Не уверен, он полностью ответит на ваш вопрос, но с вашим кодом много проблем.
Что касается распараллеливания, у вас есть несколько вложенных разделов omp.Благодаря вложенному параллелизму каждый поток создает в каждом разделе max_threads новые потоки.Так что если max_threads = 10 с 3-мя уровнями вложенности, вы получите 1000 потоков !!Без вложенного параллелизма, который кажется вашей ситуацией, внутренние параллельные параллели просто игнорируются.Поэтому удалите их.
Что касается omp, то внутренние сокращения относятся к локальным переменным потока и могут быть подавлены.Но как насчет result+=delta*p
.Это сокращение для глобальной переменной и должно обрабатываться как таковое.Настоящий код содержит ошибки.
Возможно, худшим в вашем коде является способ доступа к данным. Все обращения к вашим матрицам осуществляются в кеше недружественным способом.И что еще хуже, он запрещает оптимизацию (например, векторизацию simd) компилятором.Минимум - это транспонировать ваши матрицы (что я и сделал), но вы можете переосмыслить свой алгоритм, чтобы он больше не обращал внимания на кэш.Если вы не знаете об этих проблемах, посмотрите на что такое кеш-код .
Несколько случайных замечаний.Объявления Tijk бесполезны.При присваивании double константой, оно не должно быть int (для результата delta, s).
Не используйте время (1) для измерения времени выполнения.Есть более точные измерения с rdtsc, times (2) или clock (3) (которые я использовал).Я подозреваю, что ваш код будет очень быстрым, когда-то должным образом оптимизирован, и для правильного сравнения вы должны рассмотреть несколько циклов.Отрегулируйте количество петель, как вам нужно.И запустить несколько раз, вы программируете.Вы увидите, что время выполнения не является детерминированным.И удалить выбросы.
Последнее, но не менее важное.Вы не должны никогда не измерять производительность без оптимизации вашего кода .Используйте gcc -O2 или -O3.
#include <time.h>
// transposed versions of matrices. To get efficient transpose code, look
// at /4102494/effektivnaya-programma-transponirovaniya-matritsy-v-keshe
// it is a quick and dirty hack,
// but you should rethink your algorithms to use properly caches
double Tmatr[m][m];
double Ttrasposta[cols][m];
clock_t start, end;
start=clock(); //tic
#define NLOOPS 100
// to adjust
// run the code several times
for(int l=0; l<NLOOPS; l++)
{
double result = 0.0;
#pragma omp parallel for reduction(+:result)
for (int t = 0; t < cols; ++t) {
double delta = 1.0;
for (int k = 0; k < m; ++k) {
delta *= Ttrasposta[t][k];
}
double p = 1.0;
for (int j = 0; j < m; j++) {
double s = 0.0;
for (int i = 0; i < m; i++) {
s += Ttrasposta[t][i] * Tmatr[j][i];
}
p *= s;
}
result += delta * p;
}
permanent = result / cols;
}
end=clock();//toc
cout << permanent << endl;
cout << "Time: " << (double)(end-start) << endl ;
Последнее замечание.Теперь с чистым кодом вы можете поэкспериментировать со своей программой.Я не смог этого сделать, потому что отсутствуют важные данные: например, размер матриц.M = 4 или 100000?То же самое для cols.Это может серьезно изменить состояние параллелизации.Вот почему вы всегда должны предоставлять Минимальный, завершенный, проверяемый пример .
В зависимости от этих значений, может быть, лучше свернуть вашу 'omp параллель для'.