2010-08-21 13 views
13

A medida que leo más y más profundamente en el significado de la palabra clave volatile, sigo diciéndome a mí mismo "esto es camino a implementación, esto no debería ser parte de un lenguaje de programación de alto nivel".
Quiero decir, el hecho de que las CPU almacenen en caché los datos debería ser interesante para el compilador JIT, no para el programador C#.C# - ¿Realmente se necesita "volátil" como palabra clave?

Una alternativa considerable podría ser un atributo (por ejemplo, VolatileAttribute).

¿Qué opinas?

+0

+1 Creo que VolatileAttribute está bien en esta situación. Pero no sé por qué MS lo convierte en una palabra clave. –

+0

C# se supone que es similar a C++, y C++ ya tiene 'volátil'. Como decidieron que necesitaban esta funcionalidad (y acepto), y la palabra clave ya está en el conjunto "similar", ¿por qué no usarla? – Blindy

+0

@Blindy: C++ volátil tiene un patrón de uso diferente, por lo que me habría mantenido al margen. –

Respuesta

2

IIIRC, en C++ volátil se refería principalmente a E/S mapeadas en memoria en lugar de caché. Si lees el mismo puerto dos veces, obtienes respuestas diferentes. Aún así, estoy de acuerdo con su evaluación de que esto se expresa más claramente en C# como un atributo.

Por otro lado, la mayoría de los usos reales de volátiles en C# pueden entenderse mejor como bloqueo de roscas de todos modos, por lo que la elección de volátiles puede ser un poco desafortunado.

Editar: Sólo para añadir: dos enlaces para mostrar que en C/C++ `volátil es explicitlynot para multihilo.

3

Usar un atributo sería aceptable, si hubiera sido al revés, es decir, el compilador supondría que todos los valores variables son volátiles, a menos que se marque explícitamente con un atributo que indique que es seguro. Eso sería increíblemente disuasivo para el rendimiento.

Por lo tanto, se supone que, dado que cambiar el valor de una variable fuera de la vista del compilador es una aberración, el compilador asumiría que no está ocurriendo.

Sin embargo, que podría suceder en un programa por lo que el lenguaje en sí debe tener una manera de mostrar eso.

Además, parece confundido acerca de "detalles de implementación". El término se refiere a cosas que hace el compilador a sus espaldas. Este no es el caso aquí. Su código está modificando un valor fuera de la vista del compilador. Como está en su código, siempre será cierto. Por lo tanto, el idioma debe poder indicar eso.

8

Creo que tiene un seguimiento lateral. Todo el material técnico sobre el almacenamiento en caché, etc., es parte de un intento de explicarlo en términos de bajo nivel. La descripción funcional de volátil sería "Podría ser compartido". Dado que por defecto nada se puede compartir entre hilos, esto no es del todo extraño. Y creo que es lo suficientemente fundamental como para garantizar una palabra clave sobre un atributo, pero supongo que fue en gran medida influenciado por decisiones históricas (C++)

Una forma de reemplazar/optimizar es con llamadas VolatileRead() y VolatileWrite(). Pero eso es aún más 'implementación'.

5

Bueno, ciertamente estoy de acuerdo, es bastante horrible que tal detalle de implementación esté expuesto. Sin embargo, es exactamente el mismo tipo de detalle expuesto por la palabra clave . Todavía estamos muy lejos de que el generador de errores se elimine por completo de nuestro código.

Los chicos del hardware tienen mucho trabajo por hacer. La palabra clave volátil importa una gran cantidad de núcleos de CPU con un modelo de memoria débil.El mercado no ha sido amable con ellos, el Alpha y el Itanium no lo han hecho bien. No estoy muy seguro de por qué, pero sospecho que la dificultad de escribir código de hebra sólida para estos núcleos tiene mucho que ver con eso. Hacerlo mal es toda una pesadilla para depurar. La verbosidad en la documentación de MSDN Library para volátiles se aplica a este tipo de procesadores, de lo contrario es bastante inapropiado para núcleos x86/x64 y hace que suene que la palabra clave está haciendo mucho más de lo que realmente hace. Volátil simplemente evita que los valores variables se almacenen en registros de CPU en esos núcleos.

Desafortunadamente, volátil todavía importa en los núcleos x86 en muy circunstancias selectas. Todavía no he encontrado ninguna evidencia de que importe en núcleos x64. Por lo que puedo decir, y respaldado por el código fuente en SSCLI20, la instrucción Opcodes.Volatile es una opción no operativa para el jitter x64, sin cambiar ni el estado del compilador ni emitir ningún código de máquina. Eso se dirige de la manera correcta.

El consejo genérico es que donde quiera que esté considerando la volatilidad, usar el candado o una de las clases de sincronización debería ser su primera consideración. Evitar que intenten optimizar su código es una micro-optimización, derrotada por la cantidad de sueño que perderá cuando su programa muestre problemas de carrera de subprocesos.

+0

Los métodos Thread.VolatileRead y Thread.VolatileWrite incluyen llamadas a Thread.MemoryBarrier. Si la palabra clave volátil es no operativa, esto significaría que la palabra clave volátil funciona de manera diferente que los métodos VolatileRead y VolatileWrite. ¡Ay! (Y no, Thread.MemoryBarrier es mejor no ser un no-operador. Las CPU x86 y x64 tienen almacenamientos intermedios de tienda que pueden dar como resultado la reordenación de la tienda seguida de carga. Almacenar seguido de carga es central para Dekker, por lo que Dekker se rompe en estos archs si las barreras de memoria no se usan. Buen recurso es http://www.cl.cam.ac.uk/~pes20/weakmemory/cacm.pdf.) –

+0

No incluyen una barrera, el titanio era mucho más voluble que eso. Flushing pendientes de lectura y escritura estaba separado. Había adquirido basura también. Creo que nunca he estado a sabiendas dentro de un radio de 500 millas de uno. No se siente como una pérdida. –

2

volatile en C# emite las barreras correctas, o vallas, que le importarían al programador que realiza el trabajo de múltiples hilos. Tenga en cuenta que el compilador, el tiempo de ejecución y el procesador pueden reordenar lecturas/escrituras hasta cierto punto (cada una tiene sus propias reglas). Aunque CLR 2.0 tiene un modelo de memoria más sólido que lo que especifica CLI ECMA, el modelo de memoria CLR aún no es el modelo de memoria más estricto, por lo que necesita volatile en C#.

Como atributo, no creo que pueda usar atributos dentro de un cuerpo de método, por lo que la palabra clave es necesaria.

Cuestiones relacionadas