OpenMP: как очистить указатель цели? - PullRequest
3 голосов
/ 27 января 2011

Я только что заметил, что следующий код не компилируется в OpenMP (в соответствии с GCC 4.5.1):

struct job {
    unsigned busy_children;
};

job* j = allocateJob(…);
// …

#pragma omp flush(j->busy_children)

Компилятор жалуется на -> в списке аргументов для сброса,и в соответствии со спецификацией OpenMP это правильно: flush ожидает в качестве аргументов список «id-выражений», что в основном означает, что разрешены только (квалифицированные) идентификаторы, без выражений.

Кроме того, в спецификации говоритсяэто около flush и указателей:

Если указатель присутствует в списке, сам указатель сбрасывается, а не блок памяти, на который ссылается указатель.

Конечно.Однако, поскольку OpenMP также не позволяет мне разыменовать указатели, я в принципе не могу сбросить указатель (цель указателя).

- Так что же со ссылками?Спецификация не упоминает их, но я не уверен, что следующее согласуется, и на самом деле очистит pointee.

unsigned& busy_children = j->busy_children;
#pragma omp flush(busy_children)

Это гарантированно сработает?

Если нет, как мне смыть пуанти?

Ответы [ 3 ]

2 голосов
/ 27 января 2011

Директива flush долгое время вызывала головную боль OpenMP ARB.Настолько, что ходили разговоры о его полном удалении - хотя это создает другие проблемы.Использование flush (list) очень трудно получить правильно, и даже у экспертов OpenMP есть много проблем с его получением.Проблема заключается в том, что способ его определения может быть перемещен компилятором в вашем коде.Это означает, что вы должны избегать использования flush (list).

Что касается вашего вопроса о возможности сбрасывать pointee, есть только один способ сделать это - использовать flush (без списка).).Это очистит всю вашу среду потоков и, как таковое, не может быть перемещено компилятором.Кажется, это «тяжелые руки», но на самом деле компиляторы довольно хорошо очищают то, что необходимо при использовании сброса без списка.

1 голос
/ 27 января 2011

Спецификация OpenMP прямо не говорит о типе переменной, но MSDN говорит, что «переменная, указанная в директиве flush, не должна иметь ссылочный тип».Это заставляет меня думать, что это не гарантирует работу.Директива flush с пустым списком переменных должна очистить всю память, так что это то, что вы можете безопасно использовать.

0 голосов
/ 21 июня 2018

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

...