Привет, я написал очень простой пример того, как использовать omp flush для обмена данными между производителями и потребителями. Я нашел странное поведение.
int a=-1;
int flag=1;
int count=0;
#pragma omp parallel num_threads(2)
{
int TID;
TID=omp_get_thread_num();
#pragma omp sections
{
#pragma omp section /////////// Producer
{
for(int i=0; i<9;i++)
{
a=i;
#pragma omp flush(a)
flag=1;
printf("Producer a: %d flag:%d TID %d \n",a,flag,TID);
while(flag)
{
#pragma omp flush(flag)
}
}
flag=2;
#pragma omp flush(flag)
} // end producer
#pragma omp section /////////// Consumer
{
while(1) {
count++;
flag=0;
while(!flag)
{
#pragma omp flush(flag)
}
#pragma omp flush(a)
printf("Consumer a: %d Flag: %d count %d TID %d \n",a,flag,count,TID);
if (flag==2) break; // no more data
} // end while(1)
}// end consumer
}// end sections
Использование этого очень простого кодавыдаст ошибочный вывод: Производитель a: 0 флаг: 1 TID 0
Производитель a: 1 флаг: 1 TID 0
Потребитель a: 1 Флаг: 1 счет 1 TID 1
Производитель a: 2 flag:1 TID 0
Потребитель a: 2 Флаг: 1 счет 2 TID 1
Производитель a: 3 флага: 1 TID 0
Потребитель a: 3 Флаг: 1 count 3 TID 1
Производитель a: 4флаг: 1 TID 0
потребитель a: 4 флаг: 1 счет 4 TID 1
производитель a: 5 флаг: 1 TID 0
потребитель a: 5 флаг: 1 счет 5 TID 1
производитель a: 6 флаг: 1 TID 0
потребитель a: 6 флаг: 1 счет 6 TID 1
производитель a: 7 флаг: 1 TID 0
потребитель a: 7 флаг: 1 счет 7 TID 1
Производитель a: 8 флаг: 1 TID 0
Потребитель a: 8 Флаг: 1 счет 8 TID 1
Потребитель a: 8 Флаг: 2 count 9 TID 1
Ошибка в том, что первый элемент данныхПроизведенное = 0 игнорируется потребителем.Если я просто инвертирую порядок секций, позволяя производителю быть потоком 1, тогда все в порядке ..... Флаг производителя: 0: 1 TID 1
Потребитель: 0: Флаг 1: 1 счет 1 TID 0
Производитель a: 1 флаг: 1 TID 1
Потребитель a: 1 Flag: 1 count 2 TID 0
.... В чем моя ошибка?
..... После интересного обсужденияс помощью Ejd (спасибо) код был отредактирован так:
int a=-1;
int flag=0;
int count=0;
#pragma omp parallel num_threads(2)
{
int TID;
TID=omp_get_thread_num();
#pragma omp sections
{
#pragma omp section /////////// Consumer
{
while(1) {
count++;
if (flag) printf("Consumer a: %d Flag: %d count %d TID %d \n",a,flag,count,TID);
flag=0;
while(!flag)
{
#pragma omp flush(flag)
}
if (flag==2) break; // no more data
} // end while(1)
}// end consumer
#pragma omp section /////////// Producer
{
for(int i=0; i<9;i++)
{
a=i;
printf("Producer a: %d flag:%d TID %d \n",a,flag,TID);
flag=1;
while(flag)
{
#pragma omp flush(flag,a)
}
}
flag=2;
#pragma omp flush(flag)
} // end producer
}// end sections
Теперь это прекрасно работает.Спасибо!