OpenMP Расположение частных переменных?

Где размещаются частные переменные openmp? В каждом стеке потоков, динамически или через какой-то общий массив или что-то в этом роде?


person James Cotter    schedule 25.01.2012    source источник


Ответы (2)


Спецификация OpenMP не указывает, должны ли эти переменные размещаться в стеке или в куче (и находятся ли они в куче, если она находится в общем массиве или если для каждого потока выделяется один объект). Обычно я бы предположил, что частные переменные размещаются в стеке (нет причин не делать этого, и в целом это более эффективно). Согласно руководству, такое поведение используется в libgomp (реализация, используемая gcc) в по крайней мере, ничего не известно о других реализациях (хотя я не вижу причин, по которым они не должны делать то же самое).

person Grizzly    schedule 25.01.2012
comment
Логично, я бы так и подумал. Спасибо. - person James Cotter; 26.01.2012

OpenMP ничего не указывает о размещении частных переменных.
Есть два варианта: куча и стек.
Если мы подумаем о том, что каждый поток выполняет меньшее количество инструкций, для главного потока имеет смысл выделить частные переменные, как показано ниже.

Код :

1: set_threads(n)
2: #pragma omp parallel private(var)
3: { 
4:   var = ...
5:}

Машинный код:
строка 2: var_ptr = новые переменные [n]
строка 4: var_ptr [get_thread_id()] = ...

Но приведенный выше код приведет к большому количеству ложного совместного использования частных переменных в разных потоках. Поэтому я думаю, что компилятору будет разумно размещать их в стеке каждого потока.

person prathmesh.kallurkar    schedule 25.01.2012
comment
У вас есть ссылки на это? Похоже, что в спецификации это не указано, и это кажется неэффективным по сравнению с простым выделением памяти в стеке. Кроме того, согласно этому, по крайней мере, libgomp так не делает. Помимо того, какие директивы существуют, чтобы избежать освобождения данных private, по крайней мере, похоже, их нет. - person Grizzly; 26.01.2012
comment
Shared != private, и показанный вами псевдокод, безусловно, совершенно неверен, поскольку этот код провоцирует ложное совместное использование, которое является основным убийцей производительности на большинстве (= согласованных с кешем) архитектур ЦП. - person Konrad Rudolph; 26.01.2012
comment
@выше .. о да, чувак .. теперь я понял твою точку зрения. Проблема в том, что я думал с точки зрения разработчиков о минимизации количества выполняемых инструкций. размещение частных переменных в куче гарантирует, что только главный поток выполняет malloc по сравнению с каждым потоком, уменьшающим указатель стека для размещения частной переменной. но это, несомненно, приведет к ложному совместному использованию частных переменных в долгосрочной перспективе. Спасибо, что указали на это. PS: пожалуйста, посмотрите на отредактированный пост. - person prathmesh.kallurkar; 26.01.2012
comment
@prathmesh.kallurkar: В вашей логике все еще есть проблема. Уменьшение указателя стека чрезвычайно дешево, а malloc совсем не то. Я не знаю точных цифр, но я бы оценил malloc в >100 тактовых циклов, в то время как выделение стека, вероятно, будет в 1 такт (не считая инициализации в любом случае), который в любом случае, вероятно, спрятан где-то в конвейере (и может понадобиться в любом случае). Таким образом, даже без учета ложного распределения стека обмена, скорее всего, будет дешевле. - person Grizzly; 26.01.2012
comment
@grizzly это была всего лишь условная стоимость, о которой я думал ... да, конечно, один malloc дороже, чем что-то вроде esp = esp-4. - person prathmesh.kallurkar; 27.01.2012
comment
Конструкция @Grizzly thread_private поддерживает значение частных переменных в параллельных регионах. Это было бы возможно только в том случае, если их расположение не было освобождено после окончания первого параллельного блока. - person prathmesh.kallurkar; 30.01.2012