質問

CおよびC ++では、変数を volatile としてマークできますこれは、宣言オブジェクトの外部で変更される可能性があるため、コンパイラは最適化しないことを意味します。 Delphiプログラミングに同等のものはありますか?キーワードでない場合、おそらく回避策ですか?

Absolute を使用することを考えていましたが、確信が持てず、他の副作用が発生する可能性があります。

役に立ちましたか?

解決

簡単な答え:いいえ。

ただし、このアプローチに従えば、コンパイラの保守的なアプローチが読み取りまたは書き込みの数を変更する状況は認識していません。

クロススレッドで表示される場所を読み取る場合、さらに操作を行う前に、その値をローカルに保存してください。同様に、書き込みを単一の割り当てに制限します。

Delphiコンパイラは、式の間にインライン化されていないメソッドへの呼び出しがある場合、コンパイラがプロシージャ間の最適化を行わないため正しくないため、非ローカルロケーション式でCommon Subexpression Removal(CSE)を実行しませんシングルスレッドコードでも。

したがって、InterlockedExchange()を使用して読み取りおよび書き込みを実行し、これを強制することができます。さらに、これにより完全なメモリバリアが発生するため、プロセッサは読み取りと書き込みのいずれも並べ替えません。

他のヒント

モバイル開発向けDelphi言語ホワイトペーパー、Delphiのモバイルコンパイラは をサポートしています。 [volatile] 属性が最初に導入されて以来:

  

volatile 属性は、異なるスレッドによって変更される可能性のあるフィールドをマークするために使用されます。そのため、コード生成は、レジスターまたは別の一時メモリー位置の値のコピーを最適化しません。

     

volatile 属性を使用して、次の宣言をマークできます。

     
      
  • 変数(グローバルおよびローカル)
  •   
  • パラメータ
  •   
  • レコードまたはクラスのフィールド。
  •   
     

volatile属性を使用して、次の宣言をマークすることはできません:

     
      
  • タイプ
  •   
  • 手順、関数、またはメソッド
  •   
  •   
     

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

Delphi 10.1 Berlinから、デスクトップコンパイラは [volatile] もサポートするようになりました。

すべてのコンパイラでサポートされる属性

  

現在、すべてのDelphiコンパイラは次の属性をサポートしています。

     

同等のものは知りません。また、 absolute ディレクティブが役立つとは思いません。 absolute を使用すると、同じアドレスを使用する2つの変数を使用できますが、コンパイラがそのメモリへの参照を最適化することを妨げるとは思いません。

ポインタを使用して自分で管理できると思います。コンパイラーがポインター値の取得を最適化する限り、その方法では、アドレスに格納された値が前回読み取ったときと同じであると想定するべきではありませんが、これは純粋な推測です。

Delphi for .Netにもキーワードはありませんが、.Netプラットフォームにはutil関数があります。 Thread.VolatileRead および Thread.VolatileWrite

動的に割り当てられたポインターを使用しますか?

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

これにより、コンパイラが整数値にレジスタを使用しないようにする必要があります(ただし、アドレスにレジスタを使用する場合があります)。ただし、それがvolatileと比較されるかどうかはわかりません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top