3

#pragma omp atomicOpenMP標準を実装するコンパイラーは、特別なハードウェア命令を利用して、ディレクティブアトミックに従って特定のメモリー更新を行い、高価なロックを回避することができますが、義務ではありません。http://gcc.gnu.org/onlinedocs/gccint/OpenMP.htmlによると、GCCは次のようにアトミックアップデートを実装しています。

可能な限り、組み込みのアトミック更新が使用されます。それが失敗した場合、コンペアアンドスワップループが試行されます。それも失敗した場合は、式の周りの通常のクリティカルセクションが使用されます。

  1. 特定のマシンとGCCバージョンで実際に使用されているのは3つのうちどれかをどのように判断できますか?プログラムのプロファイルを作成したり、生成されたバイトコードを調べたりせずに見つけるために設定できるGCCの冗長オプションはありますか?

  2. 特定のマシンの結果を予測できるように、アトミック加算/インクリメントなどの命令を提供するCPU /アーキテクチャをリストしたドキュメントはありますか?

さまざまなマシンでGCCバージョン4.2から4.6を使用しています。

4

2 に答える 2

1

オプションを使用して、中間ツリー表現を確認-fdump-tree-allできます。そのオプションを指定すると、GCCはいくつかの中間ステップでファイルのセットを書き込み、ツリーに適用される連続する変換を観察できます。.ompexpOpenMP式が具体的な実装に展開された直後のツリーが含まれているため、このファイルはここで特に重要です。

たとえばparallel、次の単純なコードの領域内のブロック:

int main (void)
{
    int i = 0;

    #pragma omp parallel
    {
       #pragma omp atomic
       i++;
    }

    return i;
}

64ビットLinux上のGCC4.7.2によって次のように変換されます。

;; Function main._omp_fn.0 (main._omp_fn.0, funcdef_no=1, decl_uid=1712, cgraph_uid=1)

main._omp_fn.0 (struct .omp_data_s.0 * .omp_data_i)
{
  int D.1726;
  int D.1725;
  int i [value-expr: *.omp_data_i->i];
  int * D.1723;
  int * D.1722;

<bb 2>:
  D.1722_2 = .omp_data_i_1(D)->i;
  D.1723_3 = &*D.1722_2;
  __atomic_fetch_add_4 (D.1723_3, 1, 0);
  return;

}

最終的には次のようになります。

00000000004006af <main._omp_fn.0>:
  4006af:       55                      push   %rbp
  4006b0:       48 89 e5                mov    %rsp,%rbp
  4006b3:       48 89 7d f8             mov    %rdi,-0x8(%rbp)
  4006b7:       48 8b 45 f8             mov    -0x8(%rbp),%rax
  4006bb:       48 8b 00                mov    (%rax),%rax
  4006be:       f0 83 00 01             lock addl $0x1,(%rax)
  4006c2:       5d                      pop    %rbp
  4006c3:       c3                      retq

2番目の質問については、GCCがどのように構築されたかにも依存する可能性があります。

于 2012-12-07T11:32:12.477 に答える
0

GCCはマクロを定義します

#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 1

それぞれの操作が利用可能な場合。

一般に、複数のプロセッサをサポートするアーキテクチャでは、コンペアアンドスワップ(CASまたはLL / SCのいずれかの形式)が常に期待できます。

さらに、x86には、アトミックなインクリメントとデクリメントがあります。

于 2012-12-07T11:31:40.417 に答える