2016-10-22 3 views
1

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

Пример:

shared bool someNumberIsBig; 

// ... 

void main() 
{ 
    uint id = gl_LocalInvocationID.x; 
    uint gid = gl_GlobalInvocationID.x; 

    if (id == 0) someNumberIsBig = false; 
    memoryBarrierShared(); 
    barrier(); 

    uint oneNumber = someBuffer[gid]; 

    if (oneNumber > 5) someNumberIsBig = true; // WOW that's big 
    memoryBarrierShared(); 
    barrier(); 

    if (someNumberIsBig) 
    { 
     // do some work, with dynamic uniformity even, and with an 
     // assurance that at least one number was indeed big... or not?? 
    } 
} 

Это кажется простым для меня, но, возможно, конкурируя пишет в том же месте может вызвать проблему каким-то образом. Я полагаюсь на какое-либо неопределенное или специфическое для реализации поведение здесь?

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

ответ

0

Общая память всегда дорогая. Вы можете увидеть довольно хорошее объяснение, почему из статьи false sharing.

Но если вы все еще хотите использовать общую память, оно поддерживается. Единственная проблема с ними - некогерентная память и порядок выполнения. Но ваш пример решает как с барьером памяти, так и с барьером исполнения. Если вы хотите выполнять более сложные операции с разделяемой памятью, тогда вам нужно использовать атомные встроенные функции. Более подробную информацию можно найти по телефону OGL wiki.