Pregunta

En C y C ++, una variable se puede marcar como volatile , lo que significa que el compilador no lo optimizará porque puede ser modificado externamente al objeto declarante. ¿Hay un equivalente en la programación de Delphi? Si no es una palabra clave, ¿quizás una solución alternativa?

Mi idea era usar Absoluto , pero no estaba seguro, y eso podría introducir otros efectos secundarios.

¿Fue útil?

Solución

Respuesta corta: no.

Sin embargo, no tengo conocimiento de ninguna situación en la que el enfoque conservador del compilador cambie el número de lecturas o escrituras si sigue este enfoque:

Al leer una ubicación visible de enlaces cruzados, guarde su valor en un local antes de realizar cualquier otra manipulación; de manera similar, restringir las escrituras a una sola tarea.

El compilador Delphi no realiza una eliminación de subexpresión común (CSE) en expresiones de ubicación no locales cuando hay llamadas a métodos no integrados entre las expresiones, ya que el compilador no realiza la optimización interprocedencial y, por lo tanto, no sería correcto incluso para código de un solo hilo.

Por lo tanto, es posible que desee utilizar InterlockedExchange () para hacer sus lecturas y escrituras para forzar esto; Además, esto causará una barrera de memoria completa, por lo que el procesador no volverá a ordenar las lecturas y las escrituras.

Otros consejos

Según El documento técnico Delphi Language for Mobile , los compiladores móviles de Delphi han admitido un Atributo [volatile] desde que se introdujeron por primera vez:

  

El atributo volatile se usa para marcar los campos que están sujetos a cambios por diferentes subprocesos, por lo que la generación de código no optimiza la copia del valor en un registro u otra ubicación de memoria temporal.

     

Puede usar el atributo volatile para marcar las siguientes declaraciones:

     
      
  • Variables (globales y locales)
  •   
  • Parámetros
  •   
  • Campos de un registro o una clase.
  •   
     

No puede usar el atributo volátil para marcar las siguientes declaraciones:

     
      
  • Tipo
  •   
  • Procedimientos, funciones o métodos
  •   
  • Expresiones
  •   
     

type
  TMyClass = class
  private
    [volatile] FMyVariable: TMyType;
  end;

A partir de Delphi 10.1 Berlin, los compiladores de escritorio ahora también admiten [volatile] .

Atributos compatibles con todos los compiladores

  

Ahora, todos los compiladores de Delphi admiten los siguientes atributos:

     

No conozco ningún equivalente, ni creo que la directiva absoluta te ayude. absoluto le permite tener dos variables que usan la misma dirección, pero no creo que impida que el compilador optimice las referencias a esa memoria.

Me imagino que podrías usar un puntero y manejarlo tú mismo. De esta forma, independientemente de lo que haga el compilador para optimizar la recuperación del valor del puntero, no debe asumir que el valor almacenado en la dirección es el mismo que la última vez que lo leyó, pero esto es pura especulación.

Delphi para .Net tampoco tiene la palabra clave, pero la plataforma .Net tiene funciones útiles para ello. Consulte Thread.VolatileRead y Thread.VolatileWrite .

¿Usar punteros asignados dinámicamente?

var
  MyVarPtr: ^integer;
begin
  New(MyVarPtr);
  MyVarPtr^ := 5;
...

Esto debería evitar que el compilador use un registro para el valor entero (pero podría seguir usando uno para la dirección). Sin embargo, no estoy seguro de cómo se compara eso con la volatilidad.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top