2015-05-05 29 views
15

Moje pytanie jest dość proste. Dlaczego nie jest std::atomic<double>implemented completely? Wiem, że ma do czynienia z zablokowanym dostępem zmiennym. Ale tak naprawdę nie widzę, dlaczego to nie powinno być możliwe na podwójnym.Dlaczego nie jest w pełni zaimplementowane atomowe podwójne?

Podano, że można użyć dowolnego typu trivially copyable. I oczywiście podwójne jest wśród nich. Więc podstawowe operacje powinny być w porządku (ustawienie, czytanie itp.). Jednak w liczbach całkowitych możliwy jest dodatkowy zestaw operacji (fetch_add, ++, + =, etc).

Podwojenie niewiele różnią się od tych typów. Jest natywna, banalnie kopiowana itd. Dlaczego standard nie zawierał podwójnego z tymi typami?

+2

Sądzę, że powodem jest to, że większość procesorów nie obsługuje atomowych operacji "podwójnych". Jak więc to wdrożyć? – Angew

+0

Czy 'double' jest nawet trywialnie kopiowalny w ścisłym tego słowa znaczeniu, widząc jak jego pamięć nie jest identyczna z pamięcią rejestru na większości obecnych procesorów? Ale nawet jeśli tak, to czy w ogóle ma sens wykonywanie operacji atomowych na danych zmiennoprzecinkowych? Można by powiedzieć: "pewnie, czemu nie?", Ale trudno mi sobie wyobrazić, dlaczego ktoś chciałby coś takiego zrobić. Liczby całkowite i wskaźniki oraz wskaźniki podwójnego typu są klasyfikowane jako duże liczby całkowite, na pewno. Ale dane zmiennoprzecinkowe? – Damon

+0

@Damon To może brzmieć naiwnie, ale jeśli mam podwójną wartość w klasie. Chcę napisać to na 1 wątku i przeczytać na innym. Atomic, wydaje mi się, że mam iść. – laurisvr

Odpowiedz

15

std::atomic<double> jest obsługiwany w tym sensie, że można go utworzyć w swoim programie i będzie działał zgodnie z regułami C++ 11. Możesz wykonywać z nim ładunki i magazyny oraz porównywać je i tym podobne.

standard określa, że ​​operacje arytmetyczne (+, * + =, &, itd.) Są umieszczone tylko na atomistyki o „integralne” typów, więc std::atomic<double> nie mają żadnego z tych działań określonych.

Rozumiem, że ze względu na niewielkie poparcie dla operacji pobierania lub innych operacji arytmetycznych dla typów zmiennoprzecinkowych w obecnie używanym sprzęcie, standard C++ nie zapewnia operatorom ich, ponieważ musieliby być wdrażane nieefektywnie.

(edycja). Na marginesie, std::atomic<double> w VS2015RC jest bez blokady.

8

Standardowa biblioteka wymusza std::atomic<T>, gdzie T jest dowolnym typem TriviallyCopyable. Od double jest TriviallyCopyable, std::atomic<double> powinien się skompilować i działa doskonale.

Jeśli nie, masz wadliwą bibliotekę.

przykład: http://goo.gl/QhaphY

Edit: skoro komentarz wyjaśnienia pytanie:

katalogu C++ norma określa konkretne specjalizacje podstawowych integralnych typów. (tj. typy zawierające liczby całkowite, które muszą być obecne w danym języku). Te specjalizacje mają dodatkowe wymagania w przypadku ogólnym atomowej, w które muszą wspierać:

  • fetch_add
  • fetch_sub
  • fetch_and
  • fetch_or
  • fetch_xor
  • operator ++
  • operatora -
  • Operatory porównawcze i przypisania

OR, XOR, I oczywiście nie dotyczą typów zmiennoprzecinkowych, a nawet porównania stają się trudne (ze względu na konieczność obsługi epsilonu). Tak więc wydaje się nierozsądne, aby opiekunowie bibliotek udostępniali określone specjalizacje, gdy nie ma żadnego przypadku, aby poprzeć żądanie.

Nic nie stoi na przeszkodzie, by uniemożliwić udzielenie tej specjalizacji przez bibliotekę w mało prawdopodobnym przypadku, gdy dana architektura obsługuje atomową wyłączność - lub dwa podwójne (nigdy nie będzie!).

+1

Powinienem być bardziej przejrzysty. Rozwiążę nieco moje pytanie. Ale na stronie, do której linkowałem w pytaniu. Wymieniono szereg typów, które mają pełną specjalizację std :: atomic <>. Podwój nie jest wśród nich. – laurisvr

+1

@laurisvr zaktualizowana odpowiedź w odpowiedzi –

+0

Atomowe AND jest istotne dla 'fabs()' (czyszczenie bitu znaku). XOR/OR może również z pożytkiem zepsuć bit znaku. Ciekawostka: propozycja standardów C++ (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0020r5.html) planuje dodać 'fetch_add' do atomowych typów zmiennoprzecinkowych, ponieważ najwyraźniej część sprzętu obsługuje je wydajnie. Zobacz także [Atomowy podwójny zmiennoprzecinkowy lub wektor wektorowy SSE/AVX na x86_64] (https://stackoverflow.com/questions/45055402/atomic-double-floating-point-or-sse-avx-vector-load-store -on-x86-64) dla perspektywy asm i niektóre nieefektywne wyjście kompilatora :( –