Параллельный OMP для не сильно ускоряет цикл, хотя загрузка процессора идет на 100 процентов - PullRequest
0 голосов
/ 24 июня 2019

Я пытаюсь ускорить несколько вычислений, но, хотя все ядра заняты моими вычислениями, ускорение невелико.

Работает на I7 7800 (6 ядер, 12 потоков) с 64-битной Windows 10.

#include "omp.h"
int i;
int j;
double tempval1;
double tempval2;
double tempval3;
int col1=4;
int row1=37500000;
double *in1 = (double *)malloc(col1 * row1 * sizeof (double));
double *inim1 = (double *)malloc(col1 * row1 * sizeof (double));
double *in2 = (double *)malloc(col1 * row1 * sizeof (double));
double *inim2 = (double *)malloc(col1 * row1 * sizeof (double));
double *in8 = (double *)malloc(col1 * sizeof (double));


omp_set_num_threads(12);

    for (i = 0; i < col1; ++i)
    {
        tempval3=in8[i];// in8 individual for each column
        #pragma omp parallel for private(tempval1,tempval2),schedule(dynamic,16384)
        for (j = i * row1; j < ((i + 1) * row1); ++j)
        {
            //For each element of the matrix, multiply in1 with in2, both real and imaginary part, but beforehand add in8 to in2 (only real and without altering original in2)
            tempval1=inim1[j] * inim2[j];// 
            tempval2=in1[j] * inim2[j];// 
            in1[j]=in1[j] * (in2[j] + tempval3) - tempval1;// only add to in2 but not inim2 because in8 is not complex
            inim1[j]=inim1[j] * (in2[j] + tempval3) + tempval2;  
        }
    }

Например, col1 равно 4, а row1 равно 37500000. С одним ядром я получаю 0,23 секунды, с 2 ядрами - 0,19 секунды, с 12 ядрами - 0,163 секунды, что даже не вдвое больше. С графиком или без или статическим или динамическим графиком на самом деле не имеет никакого значения. Не могу создать временную матрицу для in1 из-за нехватки памяти. Ложное разделение не должно происходить, потому что при таких больших числах row1 отдельные куски должны быть далеко друг от друга, верно? Кто-нибудь видит очевидную ошибку на моей стороне?

1 Ответ

0 голосов
/ 24 июня 2019

Единственная очевидная ошибка, которую я сразу заметил, - это ваше предположение о том, что многопоточность не имеет смысла. Но это не так. Вы никогда не увеличите скорость в 4 раза с 4 потоками, так как есть затраты на инициализацию каждого потока и объединение их позже. Еще большее увеличение производительности (в%) имеет тенденцию к снижению с добавлением большего количества потоков, что хорошо видно по вашим измерениям. Чтобы лучше понять основные понятия многопоточности, вам следует прочесть основную книгу по программированию.

Я думаю, вам стоит попробовать

#pragma omp for
Директива

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

И, как я помню из моего опыта работы с OMP, omp_set_num_threads(12); - это всего лишь рекомендация использовать 12 потоков.

Это очень хорошая практика оптимизации для измерения скорости разных подходов, вы на правильном пути.

...