OpenCL 1.2: согласованность глобальной памяти, связанная с атомарными операциями?

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

Подробности: У меня есть двоичное дерево (хранящееся в виде массива) значений, которые я хочу вычислить. Значения внутренних узлов зависят от значений, рассчитанных для их дочерних узлов. Имеется n листьев и создается n потоков, которые проходят от листа -> корень.

Для любого конкретного значения:

Предположим, есть два потока, не обязательно в одной рабочей группе:

  • оба потока атомарно увеличивают счетчик в глобальной памяти (предварительно инициализированный до 0).
  • еслиatomic_inc возвращает 0, поток возвращается (первый посетитель).
  • еслиatomic_inc возвращает 1, поток вычисляет значение для узла (используя значения для его дочерних узлов, если узел внутренний), следует по указателю/индексу к своему родительскому элементу и зацикливает этот процесс (второй посетитель).

Таким образом, потоку, обрабатывающему любой узел, гарантируется, что оба его потомка уже обработаны в «реальном времени». У меня есть рабочая реализация той же идеи, работающая с пулом потоков на ЦП.

Проблема:

Когда я читаю вычисленные значения для дочерних элементов из внутреннего узла, меньшинство из них устаревшие/неинициализированные. Фактически, даже соответствующий счетчик для дочерних элементов (который модифицируется только атомарными операциями) может давать устаревшие значения (например, 0 или 1, а не 2). Из описанной выше процедуры невозможно обработать узел, не посетив каждый из его дочерних узлов дважды.

Это подсказывает мне, что OpenCL 1.2 имеет только гарантии конечной согласованности при чтении глобальной памяти между рабочими группами в одной и той же памяти, даже если записи являются атомарными. Верна ли моя оценка (и если да, то есть ли способы обойти это)?

Я очень ценю любую помощь в этом вопросе!

ТЛ;ДР: Я знаю, что OpenCL 1.2, вообще говоря, имеет расслабленную модель памяти согласованности - применимо ли это также к атомарной записи? (И если да, то можно ли гарантировать, что операции чтения, происходящие после атомарной записи, не устарели?)

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

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

Tim 28.05.2024 18:55

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

Danimator 11.06.2024 00:33
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
102
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

uint atomic_load(volatile global uint* ptr) {
    return atomic_cmpxchg(ptr, DUMMY_VALUE, DUMMY_VALUE);
}

Где DUMMY_VALUE — это просто любое значение (единственная важная часть — то, что последние два аргумента имеют одно и то же значение).

Это работает, поскольку если *ptr == DUMMY_VALUE, DUMMY_VALUE сохраняется и также возвращается, а если они не равны, старое значение *ptr сохраняется и также возвращается.

Другой вариант — использовать atomic_or(..,0) или atomic_add(..., 0) (сложение целого числа) или что-то подобное. Это может сэкономить вам около часа общей задержки сообщения, поскольку на некотором оборудовании, поскольку сравнение и замена могут иметь большую задержку канала на один или два часа, но это, вероятно, не будет иметь измеримого значения. Рад, что вы решили свою проблему.

Tim 11.06.2024 23:25

Это, безусловно, более разумные реализации; Я предположил, не проверяя, что эти функции только устанавливают значения, а не возвращают их. Еще раз спасибо :)

Danimator 12.06.2024 09:35

Другие вопросы по теме