2010-09-13 12 views
10

Tengo una clase A que sobrecargo su operador =. Sin embargo, se requiere que tengo que hacer algo como esto:C++ volátil y sobrecarga del operador para la aplicación CUDA

volatile A x; 
A y; 
x = y; 

cual produce un error durante la compilación de

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

Si me quita volátil, es compilables. ¿Hay alguna forma de tener esto compilado sin eliminar el "volátil" (y aún así mantener el comportamiento de volátil)?


Básicamente, este es un programa CUDA en la que 'x' es una memoria compartida (todas las discusiones pueden acceder y modificar su valor). Quiero que sea "volátil" para evitar la optimización del compilador y reutilizar el valor en lugar de acceder a la dirección de la memoria.

Más sobre el problema: al principio A es simplemente un tipo primitivo, por ejemplo, entero, volátil funcionó como se esperaba y no causa ningún problema, ahora quiero que sea una clase personalizada (entero de 128 bits por ejemplo) . No estoy seguro de por qué C++ se queja en este caso, pero no con el tipo de datos primitivos.

Gracias de antemano.

Respuesta

7

Suponiendo que es necesaria la calificación volatile, deberá agregar un operador de asignación volátil a A (A& A::operator=(const A&) volatile).

const_cast<A&>(x) = y lo hará compilar, pero técnicamente causará un comportamiento indefinido, y sin duda eliminará las garantías que volatile da.

+0

Gracias! Está compilado. pero muy mal :(, me da el mismo comportamiento de – w00d

+0

no volátil @iKid: ¿qué comportamiento esperabas de 'volátil'? –

+0

Agregué una explicación a mi pregunta – w00d

2

volátil no es de mucha utilidad en el enhebrado C++ (consulte la explicación de Dave Butenhof en http://www.lambdacs.com/cpt/FAQ.html#Q56). No es suficiente para garantizar que su programa borre los datos escritos de la memoria caché local central a un punto donde otros programas puedan ver las actualizaciones en la memoria compartida, y dado que casi todos tienen varios núcleos en la actualidad, ese es un problema grave. Sugiero que utilice métodos de sincronización de subprocesamiento adecuados, como boost si sus necesidades de portabilidad coinciden, o tal vez mutexes y variables de condición POSIX, fallando las técnicas que dependen de la arquitectura como barreras de memoria u operaciones atómicas que sincronizan implícitamente la memoria entre núcleos.

Estoy seguro de que quiere que sea rápido, pero rápido e inestable no suele ser tan útil como lento y confiable, especialmente si envía un producto que solo es inestable en el hardware de su cliente.

+0

Especialmente considerando que 'pthread_mutex'es puede ser increíblemente liviano – doron

+0

¿Porque todo el mundo corre en POSIX, amirite? – Puppy

+0

@DeadMG: no, razón por la cual tenemos contenedores portátiles como Boost.Thread y la biblioteca de compatibilidad de subprocesos C++ 0x. –

2

El "volátil no es de mucha utilidad en el enhebrado de C++" el comentario es irrelevante para la pregunta, que es específica de CUDA. volátil es necesario para warp síncrono de codificación en CUDA.

1

declarar un constructor de copia

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

trabajaron para mí con NVCC. Tenga en cuenta que puede tener que pasar alrededor del tipo no primitivo solo por referencia. De lo contrario, necesitará más constructores de copias que conviertan las instancias volátiles en no volátiles siempre que el tipo no primitivo pase por valor a un parámetro no volátil. Realmente se reduce a establecer la corrección volátil (al igual que const-correctness).