Если ваша программа работает правильно в одной машине, он должен быть, потому что это на самом деле не работает параллельно в этой машине.
Ваша программа страдает от гонки в s=s+tid;
строка кода. s
- общая переменная, поэтому несколько потоков одновременно пытаются ее обновить, wh Это приводит к потере данных.
Вы можете решить эту проблему, превратив эту строку кода в атомарные операции:
#pragma omp atomic
s=s+tid;
Таким образом, только один поток может одновременно читать и обновлять переменную s
и состояние гонки не более ,
В более сложных программах вы должны использовать атомные операции или критические области только при необходимости, потому что у вас нет параллелизма в этих регионах и это приводит к ухудшению производительности.
EDIT: Как было предложено пользователем High Performance Mark, я должен отметить, что вышеприведенная программа очень неэффективна из-за атомной операции. Правильный способ сделать такой расчет (добавление к одной и той же переменной во всех итерациях цикла) заключается в реализации сокращения . OpenMP позволяет легко с помощью reduction
пункт:
#pragma omp reduction(operator : variables)
Попробуйте эту версию программы, с помощью сокращения:
#include<stdio.h>
#include<omp.h>
int main()
{
int p=1,s=1,tid;
#pragma omp parallel reduction(+:s) private(p,tid)
{
p=1;
tid=omp_get_thread_num();
p=p+tid;
s=s+tid;
printf("Thread %d P=%d S=%d\n",tid,p,s);
}
return 0;
}
Следующая ссылка объясняет критические секции, атомарные операции и сокращение более многословным способом : http://www.lindonslog.com/programming/openmp/openmp-tutorial-critical-atomic-and-reduction/
Редактирование вопроса, чтобы мы могли прочитать код, поможет. Итак, объясняем, каковы различия в выходе. Несмотря на все, что у вас, вероятно, есть * гонка данных *, которая отображается только при ее переносе с одной машины на другую. Вы пробовали использовать код на разных количествах потоков в вашей системе и получали одинаковые результаты каждый раз? –