2012-10-03 5 views
0

Когда я пытаюсь найти более подробную информацию об атомных операциях в ядре, я нашел что-то странное. Насколько я понимаю, когда атомарные операции используются на одном номере, все операции такого рода из всех потоков будут сериализованы для запуска на этом номере, чтобы сохранить целостность. Ниже приводится часть моего кода ядра:Атомная операция в ядре 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 будут выполнять фрагмент кода, но когда они пытаются выполнить операцию atom_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. Но мой эксперимент показывает, что независимо от того, насколько велика я устанавливаю значение, результат всегда прав, т. Е. T2 всегда может считывать правильное значение (newValue) независимо от того, как долго длится латентность T1. Может ли кто-нибудь помочь разобраться в этом случае? Большое спасибо.

ответ

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

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

Смежные вопросы