Атомная операция в ядре OpenCL

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

    if(atomic_cmpxchg(&A[ptr],0,-1) == -1)
        ptr = A[ptr + 3];

    //To delay
    uint k = 1000000;
    while(k--);

    A[ptr + 3] = newValue;

Для приведенного выше кода предположим, что есть только два потока T1 и T2. Как я понимаю, T1 и T2 оба выполнят фрагмент кода, но когда они пытаются выполнить операцию atomic_cmpxchg, T2 должен ждать завершения T1 (предположим, что T1 запускается первым). Как я и предполагал, когда T1 читает A[ptr], старое значение A [ptr] равно 0, поэтому оно будет изменено на -1 атомно. После этого, потому что для T1 условие не выполняется, поэтому T1 перейдет к коду задержки напрямую и будет задержано. Теперь пришло время для T2 работать с A[ptr], потому что теперь A [ptr] был установлен как -1, поэтому условие для T2 выполнено, поэтому T2 будет работать как "ptr= A[ptr + 3];", Но моя проблема в том, что после того, как T2 завершит оценку условия, он выполнит "ptr= A[ptr + 3];" немедленно, но T1 сталкивается с задержкой, поэтому значение A [ptr + 3] еще не было обновлено T1 (поскольку k настолько велико, и задержка будет очень большой). Таким образом, T2 не будет считывать актуальное значение A [ptr + 3], которое должно быть newValue. Но мой эксперимент показывает, что независимо от того, насколько велико я установил значение k, результат всегда будет правильным, то есть T2 всегда может прочитать правильное значение (newValue) независимо от того, как долго встречается задержка T1. Кто-нибудь может помочь разобраться в этом деле? Большое спасибо.

1 ответ

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

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

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