14

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

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

4

5 に答える 5

15

短い答え:いいえ。

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

クロススレッドの可視ロケーションを読み取るときは、それ以上の操作を行う前に、その値をローカルに保存します。同様に、書き込みを単一の割り当てに制限します。

Delphi コンパイラは、式の間にインライン化されていないメソッドへの呼び出しがある場合、非ローカル ロケーション式に対して共通部分式削除(CSE)を実行しません。 -スレッド化されたコード。

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

于 2008-10-24T01:27:41.123 に答える
11

The Delphi Language for Mobile Developmentホワイトペーパーによると、Delphi のモバイル コンパイラは、[volatile]最初に導入されて以来、次の属性をサポートしています。

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

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

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

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

  • タイプ
  • 手続き、機能または方法

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

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

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

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

于 2016-05-10T17:37:38.837 に答える
1

私は同等のものを知りませんし、絶対的な指示があなたを助けるとは思いません. absoluteを使用すると、同じアドレスを使用する 2 つの変数を使用できますが、コンパイラがそのメモリへの参照を最適化するのを妨げることはないと思います。

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

于 2008-10-24T01:03:00.643 に答える
1

Delphi for .Net にもキーワードはありませんが、.Net プラットフォームにはそのための util 関数があります。Thread.VolatileReadおよびThread.VolatileWriteを参照してください。

于 2008-10-24T08:01:55.180 に答える
0

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

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

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

于 2008-10-24T06:50:02.283 に答える