Есть ли способ сказать openmp, что общие данные постоянны? - PullRequest
8 голосов
/ 14 сентября 2011

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

Правильно ли я думаю об этом?

Если да, то есть ли способ сказать openmp (на fwiw компилятора intel), что некоторые из общих данныхконстанта, поэтому такое обновление кеша не требуется?

Если ответ c ++ const, есть ли простой способ превратить неконстантные данные в константные данные, фактически не перераспределяя память, как только программапрошел определенную точку во время выполнения?

ОБНОВЛЕНИЕ

Ах, хорошо.Теперь я помню, откуда у меня сложилось впечатление, что const была хорошей вещью в этом контексте: http://www.akkadia.org/drepper/cpumemory.pdf, раздел 6.4.1.Это связано с ложным разделением, когда переменные readonly, которые совместно используют строки кэша с переменными readwrite, несут штраф за то, что строка кэша помечается как исключительная переменная readwrite.В связанном документе рекомендуется, например, с помощью gcc, пометить эти переменные как __attribute__((section(something.else))), чтобы гарантировать, что они будут храниться в другом месте.

Как это происходит, это не имеет значения в моей собственной ситуации - большие массивы и контейнеры данных stlв котором гранулярность чтения / записи будет охватывать много строк кэша и которые в любом случае выделяются из разных пулов памяти.Так что они, естественно, будут расположены на разных строках кеша.Нет проблем!

Ответы [ 3 ]

8 голосов
/ 09 марта 2012

Я также просматривал эту тему и нашел общие рекомендации по производительности от Oracle:

Если переменная SHARED в параллельной области читается потоками, выполняющими эту область, но не записываетсялюбой из потоков, затем укажите эту переменную, чтобы быть FIRSTPRIVATE вместо SHARED.Это позволяет избежать доступа к переменной путем разыменования указателя и избежать конфликтов в кеше.

Руководство пользователя Oracle OpenMP API - Глава 7 - Вопросы производительности

5 голосов
/ 14 сентября 2011

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

Единственный раз, когда вы будете подвергаться накладным расходам, это когда одно из ядер выполняет запись в совместно используемые данные. В этой ситуации вы будете иметь (потенциально большие) издержки, потому что запись сделает недействительными все остальные копии этой строки кэша и заставит их захватывать ее из памяти или из другого кэша.

Другими словами, кеш обновляется только тогда, когда кто-то изменяет данные. Там нет периодического "освежения".

Итак, ответ на ваш вопрос: вам не нужно ничего делать. Нет никакого способа сообщить OpenMP или аппаратному обеспечению, что данные являются постоянными, и const не окажет никакого влияния, кроме синтаксиса.

0 голосов
/ 14 сентября 2011

const не означает, что память постоянна.Это означает, что ваш дескриптор этой памяти не может записать в нее (что немного отличается):

int i = 3;
int const& j = i;

i = 4;
std::cout << j << "\n";

будет печатать 4, даже если j ограничен i, значение было 3.

Следовательно, const может только сказать, что you не должен изменять базовые данные (и компилятор принудительно применяет их, до некоторой степени).Он ничего не говорит о самих данных, кроме случаев, когда они непосредственно применяются к данным:

char const array[] = "Some value";

Здесь хранилище равно const, значение является неизменным, и компилятор может свободно разместить его в ПЗУ..

...