Domanda

In C e C ++ una variabile può essere contrassegnata come volatile , il che significa che il compilatore non lo ottimizzerà perché potrebbe essere modificato all'esterno dell'oggetto dichiarante. Esiste un equivalente nella programmazione Delphi? Se non una parola chiave, forse una soluzione?

Il mio pensiero era di usare Absolute , ma non ne ero sicuro e questo potrebbe introdurre altri effetti collaterali.

È stato utile?

Soluzione

Risposta breve: no.

Tuttavia, non sono a conoscenza di alcuna situazione in cui l'approccio conservativo del compilatore cambierà il numero di letture o scritture se segui questo approccio:

Durante la lettura di una posizione visibile tra thread, salvarne il valore in un locale prima di eseguire qualsiasi ulteriore manipolazione; allo stesso modo, limitare le scritture a un singolo compito.

Il compilatore Delphi non esegue l'eliminazione della sottoespressione comune (CSE) su espressioni di posizione non locali quando ci sono chiamate a metodi non incorporati tra le espressioni, poiché il compilatore non esegue l'ottimizzazione interprocedurale e quindi non sarebbe corretto anche per il codice a thread singolo.

Quindi, potresti voler usare InterlockedExchange () per fare le tue letture e scritture per forzare questo; inoltre, ciò causerà una barriera di memoria piena, quindi il processore non riordinerà neanche le letture e le scritture.

Altri suggerimenti

Secondo The Delphi Language for Mobile Development , i compilatori mobili di Delphi hanno supportato un attributo [volatile] dalla prima introduzione:

  

L'attributo volatile viene utilizzato per contrassegnare i campi che sono soggetti a modifiche da diversi thread, in modo che la generazione del codice non ottimizzi la copia del valore in un registro o in un'altra posizione di memoria temporanea.

     

È possibile utilizzare l'attributo volatile per contrassegnare le seguenti dichiarazioni:

     
      
  • Variabili (globali e locali)
  •   
  • Parametri
  •   
  • Campi di un record o di una classe.
  •   
     

Non è possibile utilizzare l'attributo volatile per contrassegnare le seguenti dichiarazioni:

     
      
  • Digita
  •   
  • Procedure, funzioni o metodi
  •   
  • Espressioni
  •   
     

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

A partire da Delphi 10.1 Berlin, i compilatori desktop ora supportano anche [volatile] .

Attributi supportati da tutti i compilatori

  

Ora, tutti i compilatori Delphi supportano i seguenti attributi:

     

Non conosco alcun equivalente, né penso che la direttiva assoluta ti aiuterà. assoluto ti consente di avere due variabili che usano lo stesso indirizzo, ma non credo che impedirà al compilatore di ottimizzare i riferimenti a quella memoria.

Immagino che potresti usare un puntatore e gestirlo da solo. In questo modo qualunque cosa faccia il compilatore per quanto riguarda l'ottimizzazione del ripristino del valore del puntatore, non dovrebbe assumere che il valore memorizzato nell'indirizzo sia lo stesso dell'ultima volta che lo ha letto, ma questa è pura speculazione.

Delphi per .Net non ha neanche la parola chiave, ma la piattaforma .Net ha funzioni util per questo. Vedi Thread.VolatileRead e Thread.VolatileWrite .

Utilizzare i puntatori allocati dinamicamente?

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

Questo dovrebbe impedire al compilatore di usare un registro per il valore intero (ma potrebbe comunque usarne uno per l'indirizzo). Non sono sicuro di come questo possa essere paragonato a volatile.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top