Страница 1 из 1
OpenMP ошибка в директиве
Добавлено: 13 апр 2015, 16:11
Крылья
Ребят хочу распараллелить перемножение матриц с помощью технологии OpenMP
перед циклами я добавил директиву "#pragma omp paralell private (j, k) " чтобы параллельно выполнялся.....пытаюсь запустить , пишет "требуется имя директивы" не могу понять что он хочет........ если я уберу дерективу то матрицы будут последовательно перемножаться, а если оставлю и будет работать то они перемножаться параллельно , и в дальнейшем я могу посмотреть время выполнения и оценить разницу))))) буду благодарен за помощь!!!
Код: Выделить всё
void MatricA::basic_parallel_algorithm(double *a, double *b, double *c)
{
long t1 = clock();
int Size = N;
#pragma omp paralell for private (j, k)
{
for (i = 0; i < Size; i++)
{
for (j = 0; j < Size; j++)
{
for (k = 0; k < Size; k++)
{
c[i*Size + j] += a[i*Size + k] * b[k*Size + j];
}
}
}
}
long t2 = clock();
cout << "time--> " << t2 - t1 << endl; // вывод времени в миллисекундах
}
Re: OpenMP ошибка в директиве
Добавлено: 13 апр 2015, 17:24
Romeo
Если честно, я совсем не разбираюсь в технольгии OpenMP, но я кое-что понимаю в мультипоточности. Мне интересно, как будет вычисляться внутреннее выражение, если в нём участвуют как j, так и k? Тебе не кажется, что для того, чтобы распарралелить код, необходимо обеспечить независимость кусков друг от друга? Ведь только в этом случае их можно будет выполнять параллельно.
Re: OpenMP ошибка в директиве
Добавлено: 13 апр 2015, 17:48
Крылья
Кажется....это можно сделать, на отдельные куски пустить обычные потоки класса Thread и уже этим потокам вручную указать на какие ядра им идти (хотя по поводу как указать вручную им ядра я еще разбираюсь), но на сколько мне известно OpenMP своеобразная технология
я указал нужную мне директиву которая "private" и она задаёт список переменных, для которых порождается локальная копия в каждой нити.....и насколько я знаю задать число нитей тоже можно...но в целом эта технология будет максимально использовать весь потенциал процессора, если там 4 ядра, то на все 4 ядра паралелить и будет, если 2 то на 2 ядра......я сам только изучаю, это всё что мне известно....если в чем то ошибаюсь , то буду рад...сами поняли
Re: OpenMP ошибка в директиве
Добавлено: 13 апр 2015, 19:54
Romeo
Ну может я чего-то не понимаю и слишком глуп, но всегда считал, что распареллеливание возможно только в том случае, когда куски кода независимы. Например вот эти куски распарралеливаются без проблем, если массив arr заполнен в начале и затем не меняется во время исполнения программы:
Код: Выделить всё
for (int i = 0; i < N; ++i)
amount1 += 5*arr[i];
for (int j = 0; j < N; ++j)
amount2 += 7*arr[j];
Твой же код использует во внутреннем выражении оба значения, которые ты патаешь распараллелить. Ты собираешься по разным тредам разнести что именно? Икрементирование счётчиков? Но если они будут инкрементиться в отдельных тредах, то вычисляемые значения массива c будут вообще непредсказуемы.
Да, я, наверное, действительно чего-то не понимаю.
Есть тут специалисты в OpenMP, чтобы как-то прокомментировать код?
Re: OpenMP ошибка в директиве
Добавлено: 13 апр 2015, 22:59
somewhere
Есть тут специалисты в OpenMP, чтобы как-то прокомментировать код?
Я, как бы не специалист, но прокомментирую.
В данном случае OpenMP распараллелит только индекс I, т.е. фактически разобьет его на N диапазонов (допустим 4 для каждого ядра четырехядерного процессора). Свой диапазон для каждого из N потоков, при этом оставив полный проход по J,K (т.к. они задают отдельные ячейки памяти (private) для каждого из потоков - перезаписи тоже не произойдет)
Поскольку для каждого элемента массива С подходит только одна тройка I,J,K - то перепахивания С потоками тоже быть не должно.
Таким образом, разбив самый верхний for на части, обеспечивается распараллеливание вычислений.
А вот насчет ошибки ничем подсказать не могу - тут надо синтаксис курить, наверное
Re: OpenMP ошибка в директиве
Добавлено: 15 апр 2015, 13:56
WinMain
Во-первых: неправильно написано слово parallel.
Во-вторых: для прагмы omp parallel не приемлем оператор for.
Так что твою директиву правильно будет написать так:
Код cpp:
#pragma omp parallel private (j, k)