V1205. Data race risk. Unprotected concurrent operation with the 'foo' variable

Анализатор обнаружил в коде ошибку, вызванную одновременной работой потоков с общей переменной. Рассмотрим пример некорректного кода:

int a = 0;
#pragma omp parallel for num_threads(4)
for (int i = 0; i < 100000; i++)
{
      a++;
}

Поскольку все потоки пишут в одну и ту же область памяти и читают из нее одновременнно, значение переменной после этого цикла является непредсказуемым. Чтобы обезопасить эту операцию, ее нужно поместить в критическую секцию, либо (поскольку в данном примере операция является элементарной) использовать директиву "#pragma omp atomic". Второй вариант является более предпочтительным, так как приводит к более быстрому коду:

int a = 0;
#pragma omp parallel for num_threads(4)
for (int i = 0; i < 100000; i++)
{
      #pragma omp atomic
      a++;
}

Если же тип операции не позволяет использовать директиву "#pragma omp atomic", можно воспользоваться критическими секциями или блокировками. Критические секции являются более предпочтительным решением, так как они работают быстрее:

int a = 0;
#pragma omp parallel for num_threads(4)
for (int i = 0; i < 100000; i++)
{
      #pragma omp critical
      {
            ...
      }
}

Отметим, что V1205 не возникнет, если переменная является локальной, или код гарантированно выполняется только одним потоком (например, находится в области действия директивы "#pragma omp single").