2010-09-13 6 views
10

Ho una classe A che sovraccarico il suo operatore =. Tuttavia è necessario che ho bisogno di fare qualcosa di simile:C++ volatile e sovraccarico dell'operatore per l'applicazione CUDA

volatile A x; 
A y; 
x = y; 

che ha sollevato un errore durante la compilazione

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

Se ho rimosso volatili, è compilabile. Esiste comunque la possibilità di averlo compilato senza rimuovere il "volatile" (e mantenere comunque il comportamento di volatile)?


Fondamentalmente questo è un programma CUDA in cui 'x' è una memoria condivisa (tutte le discussioni possono accedere e modificare il suo valore). Voglio che sia "volatile" per evitare l'ottimizzazione del compilatore e riutilizzare il valore invece di accedere all'indirizzo di memoria.

Ulteriori informazioni sul problema: all'inizio A è solo un tipo primitivo, ad esempio intero, volatile ha funzionato come previsto e non causa alcun problema, ora voglio che sia una classe personalizzata (numero intero a 128 bit, ad esempio) . Non sono sicuro del motivo per cui C++ si lamenta in questo caso ma non con il tipo di dati primitivi.

Grazie in anticipo.

risposta

7

Supponendo che la qualifica volatile sia necessaria, sarà necessario aggiungere un operatore di assegnazione volatile ad A (A& A::operator=(const A&) volatile).

const_cast<A&>(x) = y lo compilerà, ma tecnicamente causerà un comportamento indefinito e rimuoverà certamente le garanzie fornite da volatile.

+0

Grazie! È compilato ma troppo male :(, mi dà lo stesso comportamento di non volatile – w00d

+0

@iKid: quale comportamento ti aspettavi da 'volatile'? –

+0

Ho aggiunto una spiegazione alla mia domanda – w00d

2

volatile non è molto utilizzato in threading C++ (vedere la spiegazione di Dave Butenhof a http://www.lambdacs.com/cpt/FAQ.html#Q56). Non è sufficiente garantire che il programma svuota i dati scritti dalla cache locale core fino a un punto in cui altri programmi possono vedere gli aggiornamenti nella memoria condivisa e, dato che quasi tutti sono multi-core al giorno d'oggi, questo è un problema serio. Ti suggerisco di usare i metodi di sincronizzazione dei thread appropriati, come boost se la portabilità ha bisogno di corrispondere, o forse mutex POSIX e variabili di condizione, in mancanza di altre tecniche dipendenti dall'architettura come barriere di memoria o operazioni atomiche che implicitamente sincronizzano la memoria tra i core.

Sono sicuro che si desidera che sia veloce, ma veloce e instabile non è generalmente utile quanto lento e affidabile, soprattutto se si spedisce un prodotto che è solo instabile sull'hardware del cliente.

+0

Specialmente considerando che 'pthread_mutex'es può essere incredibilmente leggero – doron

+0

Perché tutti gira su POSIX, amirite? – Puppy

+0

@DeadMG: no, ecco perché abbiamo wrapper portatili come Boost.Thread e la libreria di supporto del thread C++ 0x. –

2

Il commento "volatile non è molto utilizzato in threading C++" è irrilevante per la domanda, che è specifica per CUDA. volatile è necessario per la codifica sincrona warp in CUDA.

1

Dichiarare un costruttore di copia

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

lavorato per me con nvcc. Si noti che potrebbe essere necessario passare il tipo non primitivo solo come riferimento. Altrimenti avrete bisogno di più costruttori di copia che convertano le istanze volatili in non volatili ogni volta che il tipo non primitivo viene passato per valore a un parametro non volatile. Si riduce davvero a stabilire la volatilità-correttezza (molto simile alla cost-correttezza).