różnica w mfence i asm volatile ( ""::: "pamięć")

O ile dobrze zrozumiałem, mfence jest bariera pamięci sprzętowej, podczas gdy {[1] } jest bariera kompilatora. Ale, można asm volatile ("" : : : "memory") być używane w miejsce mfence.

Powodem, dla którego się pogubiłem jest ten link

Author: BeeOnRope, 2012-08-29

3 answers

[2]}cóż, bariera pamięci jest potrzebna tylko na architekturach, które mają słabą kolejność pamięci. x86 i x64 nie mają słabej pamięci. na x86 / x64 wszystkie sklepy mają ogrodzenie zwalniające, a wszystkie ładunki mają ogrodzenie nabywcze. więc, powinieneś tylko naprawdę potrzebować asm volatile ("" : : : "memory")

Aby uzyskać dobry przegląd zarówno Intela, jak i AMD, a także odniesienia do specyfikacji relavent producenta, zobacz http://bartoszmilewski.com/2008/11/05/who-ordered-memory-fences-on-an-x86/

Ogólnie rzecz biorąc rzeczy takie jak "lotne" są używane na zasadzie pola, gdzie obciążenia i zapasy do tego pola są natywnie atomowe. Tam, gdzie obciążenia i zapamiętywanie pola są już atomowe (tzn. "operacja", o której mowa, jest obciążeniem lub zapamiętywaniem pojedynczego pola, a zatem cała operacja jest atomowa) modyfikator pola lub bariery pamięci volatile nie są potrzebne na x86/x64. Bez względu na przenośny Kod.

Jeśli chodzi o "operacje", które nie są atomowe-np. ładuje lub przechowuje pole, które jest większe niż słowo natywne lub ładuje lub przechowuje do wielu pól w ramach "operacji" - sposób, za pomocą którego operacja może być postrzegana jako atomic są wymagane niezależnie od architektury procesora. generalnie odbywa się to za pomocą synchronizacji prymitywnej, takiej jak mutex. Mutexy (te, których używałem) zawierają bariery pamięci, aby uniknąć problemów, takich jak zmiana kolejności procesora, dzięki czemu nie trzeba dodawać dodatkowych instrukcji bariery pamięci. Generalnie uważam, że nie używanie synchronizacji prymitywów jest przedwczesne optymalizacja; ale natura przedwczesnej optymalizacji jest, oczywiście, 97% czasu:)

Tam, gdzie nie używasz prymitywu synchronizacji i masz do czynienia z niezmiennikiem wielu pól, ważne są bariery pamięci, które zapewniają, że procesor nie zmienia kolejności przechowywania i ładowania do różnych miejsc pamięci.

Teraz, jeśli chodzi o nie wydanie instrukcji "mfence" w asm volatile, ale użycie "memory" w liście clobber. Z tego co udało mi się przeczytać

Jeśli Twoje instrukcje asemblera uzyskują dostęp do pamięci w nieprzewidywalny sposób, dodaj 'memory' do listy rejestrów zablokowanych. Spowoduje to, że GCC nie będzie przechowywał wartości pamięci w rejestrach w całej instrukcji asemblera i nie będzie optymalizował magazynowania lub ładowania do tej pamięci.

Kiedy mówią " GCC " i nie wspominają nic o CPU, oznacza to, że odnosi się to tylko do kompilatora. Brak "mfence" oznacza, że nie ma bariery pamięci procesora. Możesz to sprawdzić, demontując wynikający binarny. Jeśli nie wydano instrukcji "mfence" (w zależności od platformy docelowej), to jasne jest, że procesor nie jest informowany o wydaniu ogrodzenia pamięci.

W zależności od platformy, na której jesteś i co próbujesz zrobić, może jest coś "lepszego" lub bardziej wyraźnego... przenośność nie wytrzymuje.

 21
Author: Peter Ritchie,
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-10-12 17:50:02
  • asm volatile ("" ::: "memory") jest tylko barierą kompilatora.
  • asm volatile ("mfence" ::: "memory") jest zarówno barierą kompilatora, jak i MFENCE
  • __sync_synchronize() jest również barierą kompilatora i pełną barierą pamięci.

Więc asm volatile ("" ::: "memory") nie uniemożliwi procesorowi zmiany kolejności niezależnych instrukcji danych per se. Jak wspomniano x86-64 ma silny model pamięci, ale zmiana kolejności w magazynie jest nadal możliwa. Jeśli do działania algorytmu potrzebna jest pełna bariera pamięci, musisz __sync_synchronize

 12
Author: ecerulm,
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
2018-09-15 08:05:00

Istnieją dwie zmiany kolejności, jedna to zmiana kolejności kompilatora, druga to zmiana kolejności procesora.

X86 / x64 ma stosunkowo silny model pamięci, ale na x86/x64 StoreLoad może się zdarzyć Zmiana kolejności (późniejsze ładunki przechodzące wcześniejsze sklepy). zobacz http://en.wikipedia.org/wiki/Memory_ordering

  • asm volatile ("" ::: "memory") jest tylko barierą kompilatora.
  • asm volatile ("mfence" ::: "memory") jest zarówno bariera kompilatora, jak i bariera procesora.

Oznacza to, że używaj tylko bariery kompilatora, możesz tylko zapobiec kompilatorowi Zmiana kolejności, ale nie można zapobiec zmianie kolejności procesora. oznacza to, że nie ma możliwości zmiany kolejności podczas kompilacji kodu źródłowego, ale zmiana kolejności może nastąpić w trybie runtime.

Więc to zależy od twoich potrzeb, które z nich użyć.
 5
Author: Derek Zhang,
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
2018-06-10 01:53:10