2016-09-08 46 views
6

Zastanawiam się nad użytecznością pamięci MemoryBarrierShared.glsl memoryBarrierShared usefulness

Rzeczywiście, kiedy szukam w dokumentacji funkcji bariery: Czytam:

Dla danego statycznego przykład bariery w cieniującego obliczeniowej, wszystkie wywołania w obrębie jednej grupy roboczej należy go wprowadzić, zanim którykolwiek są wolno kontynuować. Zapewnia to, że wartości zapisane przez jedno wywołanie przed danym statycznym instancją bariery mogą być bezpiecznie odczytane przez inne wywołania po ich wywołaniu do tego samego statycznego wystąpienia bariery. Ponieważ wywołania mogą być wykonywane w nieokreślonej kolejności między tymi wywołaniami bariery, wartości zmiennej wyjściowej na jeden wiersz lub na łatę lub dowolna zmienna współdzielona będą w wielu przypadkach niezdefiniowane.

Więc czy możemy bezpiecznie odczytać wartości po użyciu barierę, dlaczego widzimy w pewnym kodzie

memoryBarrierShared(); 
barrier(); 

lub coś nie tak jak

barrier(); 
memoryBarrierShared(); 

Więc moje pytanie brzmi: co jest celem memoryBarrier {Shared, ...} jeśli wystarczy użycie bariery?

Dla memoryBarrierBuffer/obrazu mogę zrozumieć, jeśli używamy wielu scenę, ale za wspólne, nie mam pojęcia ...

Odpowiedz

7

To jest rzeczywiście w rywalizacji w chwili obecnej.

GLSL 4.50 wyraźnie wyjaśnia, że ​​jawne bariery pamięciowe są niepotrzebne. Ten barrier w shaderze obliczeniowym zawiera wszystkie bariery pamięci.

Jednakże GLSL ES 3,20 sprawia, że ​​jednakowo jasne, że barriernie obejmuje bariery pamięci dowolnego rodzaju:

Na cieniującymi obliczeniowych, bariera ma wpływ tylko na kontroli przepływu, a nie przez sam synchronizuj dostęp do pamięci. W szczególności nie gwarantuje, że wartości zapisane w jednym wywołaniu przed daną instancją statyczną barrier() mogą być bezpiecznie odczytane przez inne wywołania po ich wywołaniu do tej samej instancji statycznej z barrier(). Aby to osiągnąć, konieczne jest użycie zarówno zapory, jak i pamięci.

szczególności trybu offline glslang kompilator zawsze użyć sformułowania GLSL ES. Jeśli więc tworzysz SPIR-V, by zasilić Vulkan, musisz przestrzegać zasad ES. Cóż, until they get that fixed, one way or another.

W ten sposób sformułowanie ES ma dużo więcej sensu, jako że pełna zapora pamięciowa dla wszystko, co jest, jest dość kosztowne. Szczególnie jeśli chcesz tylko zsynchronizować dostęp do wspólnych zmiennych.

Sugerowałbym użycie bariery pamięci obok połączenia barrier. W ten sposób twój moduł cieniujący będzie poprawny, nawet jeśli w niektórych implementacjach może być nieco wolniejszy.Jeśli jednak zamierzasz używać zapór pamięciowych wraz z połączeniami barrier, to najpierw musi pojawić się pierwsza bariera pamięci . Wykonywanie bariery pamięci po wykonaniu synchronizacji jest nieprawidłowe.