Różnica między pamięcią asm, asm i clobbering
Podczas implementacji bez blokady struktur danych i kodu czasowego często konieczne jest powstrzymanie optymalizacji kompilatora. Zwykle ludzie robią to używając asm volatile
z {[2] } na liście clobber, ale czasami widzisz tylko asm volatile
lub po prostu zwykłą asm
clobbering memory.
Jaki wpływ mają te różne stwierdzenia na generowanie kodu (szczególnie w GCC, ponieważ jest mało prawdopodobne, aby był przenośny)?
Dla odniesienia, są to ciekawe odmiany:
asm (""); // presumably this has no effect on code generation
asm volatile ("");
asm ("" ::: "memory");
asm volatile ("" ::: "memory");
3 answers
Zobacz stronę "Rozszerzony Asm" w dokumentacji GCC .
Możesz zapobiec usunięciu instrukcji
asm
, wpisując słowo kluczowevolatile
Poasm
. [...] Słowo kluczowevolatile
wskazuje, że instrukcja ma ważne skutki uboczne. GCC nie usunievolatile
asm, jeśli jest osiągalny.
I
Instrukcja
asm
bez operandów wyjściowych będzie traktowana identycznie jak lotnaasm
Instrukcja.
Żaden z Twoich przykładów nie ma podanych operandów wyjściowych, więc formularze asm
i asm volatile
zachowują się identycznie: tworzą punkt w kodzie, który nie może zostać usunięty (chyba że okaże się nieosiągalny).
asm
, która zmienia generowanie kodu - w tym przykładzie kod, który okrąża pętlę 1000 razy, zostaje wektoryzowany do kodu, który oblicza 16 iteracji pętli na raz; ale obecność asm
wewnątrz pętli hamuje optymalizację (asm
musi być osiągnięta 1000 razy).
Clobber "memory"
sprawia, że GCC zakłada, że dowolna pamięć może być dowolnie odczytywana lub zapisywana przez asm
blok, więc uniemożliwi kompilatorowi zmianę kolejności załadowań lub Przechowywanie w nim:
Spowoduje to, że GCC nie będzie przechowywać wartości pamięci w pamięci podręcznej w rejestrach w całej instrukcji asemblera i nie będzie optymalizować magazynów ani ładowania do tego pamięć.
(nie uniemożliwia to procesorowi zmiany kolejności obciążeń i przechowywania w odniesieniu do innego procesora; do tego potrzebne są prawdziwe instrukcje barierze pamięci.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:19
asm ("")
nic nie robi (a przynajmniej nie ma nic robić.
asm volatile ("")
i nic nie robi.
asm ("" ::: "memory")
jest prostym kompilatorem.
asm volatile ("" ::: "memory")
AFAIK jest taki sam jak poprzedni. Słowo kluczowe volatile
mówi kompilatorowi, że nie wolno przenosić tego bloku złożenia. Na przykład, może zostać wyciągnięta z pętli, jeśli kompilator zdecyduje, że wartości wejściowe są takie same w każdym wywołaniu. Nie jestem do końca pewien na jakich warunkach kompilator zdecyduje, że to rozumie na tyle o złożeniu, aby spróbować zoptymalizować jego rozmieszczenie, ale słowo kluczowe volatile
CAŁKOWICIE to tłumi. To powiedziawszy, byłbym bardzo zaskoczony, gdyby kompilator spróbował przenieść asm
oświadczenie, które nie miało zadeklarowanych wejść ani wyjść.
Nawiasem mówiąc, volatile
zapobiega również usunięciu wyrażenia przez kompilator, jeśli zdecyduje, że wartości wyjściowe są nieużywane. Może się to zdarzyć tylko wtedy, gdy istnieją wartości wyjściowe, więc nie dotyczy to asm ("" ::: "memory")
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-21 23:41:58
Tylko dla kompletności odpowiedzi Kevina Ballarda, Visual Studio 2010 oferuje _ReadBarrier (), _writebarrier() i _readwritebarrier (), aby zrobić to samo (VS2010 nie pozwala na montaż inline dla aplikacji 64-bitowych).
Nie generują one żadnych instrukcji, lecz wpływają na zachowanie kompilatora. Dobrym przykładem jest tutaj
MemoryBarrier () generuje lock or DWORD PTR [rsp], 0
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-22 00:55:41