Если вы используете OpenMP 3.1, есть замечательная новая функция с атомарным доступом, в данном случае вы хотите
#pragma omp atomic read
some_private_var = some_shared_var[some_index];
В этом есть две приятные вещи, одна из них подразумеваемая очистка, котораякак, например,
#pragma omp flush(some_shared_var[some_index])
перед чтением, но openmp не позволяет сбрасывать разыменованные значения.Хотя вы можете очистить без списка, все сбрасывается, поэтому это может быть дорого, если в самом внутреннем цикле какого-либо вычисления.
Другая хорошая вещь, конечно, атомарная природа чтения.Обратите внимание, что some_shared_var [some_index] может иметь произвольный размер (возможно, это структура или какой-то объект в C ++).Если какой-то другой поток хочет записать это, что, например, может произойти путем копирования всех примитивных данных внутри объекта, он не может прервать атомарное чтение.
С точки зрения издержек, для меня в любом случае это намного быстрее, чемблокирует, и если some_shared_var [some_index] является примитивным типом данных, чтение, вероятно, происходит в любом случае атомарно, но теперь мы получаем сброс.
Некоторые другие мысли:
Если не критично, что большинствопоследние значения читаются, вы можете рисковать без использования атомарного чтения.Это дает возможность читать из кэшированного значения, которое быстрее (например, регистр процессора).Просто посмотрите, не является ли some_shared_var [some_index] большим объектом, так как он мог бы быть частично записан другим потоком.
Я думаю, что атомарное чтение должно происходить откуда-то в памяти, доступной для всех процессоров,поэтому он все еще может находиться в кэш-памяти на кристалле (например, совместно используемой кэш-памяти L3), поэтому вам не нужно читать, скажем, из DRAM.Я не уверен на 100%, что это всегда так, но я подтвердил это для своего компьютера, запланировав некоторые эксперименты, в которых использование памяти ниже и выше встроенного в мой кэш процессора.