2010-09-13 14 views
10

Mam klasę A, którą przeciążam jej operator =. Jednak jest to wymagane, że muszę zrobić coś takiego:C++ lotne i przeciążenie operatora dla aplikacji CUDA

volatile A x; 
A y; 
x = y; 

który zgłosił błąd podczas kompilacji

error: no operator "=" matches these operands 
     operand types are: volatile A = A 

Jeśli usunąłem lotny, to compilable. Czy istnieje i tak, aby to skompilować bez usuwania "volatile" (i nadal zachowują zachowanie niestabilne)?


Zasadniczo jest to program CUDA, w którym „x” jest wspólna pamięć (wszystkie wątki mogą zmienić jego wartość). Chcę, aby był "niestabilny", aby uniknąć optymalizacji kompilatora i ponownie użyć wartości zamiast dostępu do adresu pamięci.

Więcej o problemie: na początku A jest typem prostym, np. Liczba całkowita, lotna działa zgodnie z oczekiwaniami i nie powoduje żadnych problemów, teraz chcę, aby była to klasa niestandardowa (na przykład 128-bitowa) . Nie jestem pewien, dlaczego C++ narzeka w tym przypadku, ale nie z pierwotnym typem danych.

Z góry dziękuję.

Odpowiedz

7

Zakładając, że kwalifikacja volatile jest konieczna, musisz dodać zmienną operatora przypisania do A (A& A::operator=(const A&) volatile).

const_cast<A&>(x) = y spowoduje, że zostanie skompilowany, ale technicznie spowoduje niezdefiniowane zachowanie i na pewno usunie gwarancje, które daje volatile.

+0

Dzięki! Jest skompilowany. ale szkoda :(, to daje mi takie samo zachowanie nielotnego – w00d

+0

@iKid: jakiego zachowania oczekiwałeś od 'volatile'? –

+0

Dodałem wyjaśnienie do mojego pytania – w00d

2

lotne nie ma wiele zastosowań w wątkach C++ (patrz wyjaśnienie Dave'a Butenhof'a na http://www.lambdacs.com/cpt/FAQ.html#Q56). Nie wystarczy upewnić się, że program opróżnia dane zapisane w pamięci podręcznej core-local do punktu, w którym inne programy mogą zobaczyć aktualizacje w pamięci współdzielonej, i biorąc pod uwagę, że w dzisiejszych czasach prawie wszyscy są wielordzeniowymi, jest to poważny problem. Sugeruję użycie odpowiednich metod synchronizacji wątków, takich jak boost, jeśli twoje potrzeby przenośności do niego pasują, lub może POSEX muteksy i zmienne warunkowe, nie działające w bardziej zależnych od architektury technikach, takich jak bariery pamięci lub operacje atomowe, które implicytnie synchronizują pamięć między rdzeniami.

Jestem pewien, że chcesz, aby była szybka, ale szybka i niestabilna nie jest na ogół tak użyteczna, jak powolna i niezawodna, szczególnie jeśli wysyłasz produkt, który jest niestabilny tylko na sprzęcie klienta.

+0

Szczególnie biorąc pod uwagę, że 'pthread_mutex'es może być niewiarygodnie lekki – doron

+0

Ponieważ każdy działa na systemie POSIX, amirite? – Puppy

+0

@DeadMG: nie, dlatego mamy przenośne opakowania takie jak Boost.Thread i biblioteka obsługi wątków C++ 0x. –

2

"Lotny jest mało użyteczny w wątkach C++" komentarz jest nieistotny dla pytania, które jest specyficzne dla CUDA. lotny jest potrzebny do kodowania synchronicznego w CUDA.

1

Deklarowanie konstruktor kopiujący

volatile A& operator=(volatile A&) volatile; 

pracował dla mnie z nvcc. Zwróć uwagę, że możesz ominąć typ niepochodny jedynie przez odniesienie. W przeciwnym razie będziesz potrzebował więcej konstruktorów kopii, które zamieniają instancje lotne na nielotne, gdy typ niepochodzący jest przekazywany wartością do nieulotnego parametru. To naprawdę sprowadza się do ustalenia lotnej poprawności (podobnie jak poprawność const).

Powiązane problemy