OpenMPは実際にはpthreadsにコンパイルされたマクロのセットであることを理解しています。残りのコンパイルが行われる前にpthreadコードを見る方法はありますか? GCCを使ってコンパイルしています。openmpをpthreadsにコンパイルするCコード
答えて
最初に、OpenMPはではありません。単純なマクロセットです。 pthreadのようなコードへの単純な変換が見られるかもしれませんが、OpenMPはそれ以上のランタイムサポートを必要とします。
GCCのOpenMPの実装がコンパイラのバックエンド(またはミドルエンド)で行われているため、少なくともGCCでは、pthreadされたコードは表示されません。変換はIR(中間表現)レベルで行われます。したがって、プログラマーの観点からは、コードが実際にどのように変換されているかを見るのは容易ではありません。
しかし、いくつかの参考文献があります。
(1)インテルのエンジニアは、インテルC/C++コンパイラでのOpenMPの実装の偉大な概要を提供:
http://www.drdobbs.com/parallel/how-do-openmp-compilers-work-part-1/226300148
http://www.drdobbs.com/parallel/how-do-openmp-compilers-work-part-2/226300277
(2)あなたは見てみましょうことGCCのOpenMPの実装の:
https://github.com/mirrors/gcc/tree/master/libgomp
012を参照してください。はpthreadを使用し、loop.c
には並列ループ構成の実装が含まれています。
openmpでテストしていません。しかし、コンパイラオプション-E
は、前処理後にコードを提供するはずです。
OpenMPは、マクロではなく、コンパイラディレクティブのセットです。 C/C++では、これらのディレクティブは#pragma
拡張メカニズムで実装されていますが、Fortranでは特別なフォーマットのコメントとして実装されています。これらの指示文は、シリアルコードをパラレルに変換するために、特定のコード変換を実行するようにコンパイラに指示します。
純粋なpthreadsコードへの変換としてOpenMPを実装することは可能ですが、これはめったに行われません。 OpenMPの仕組みの大部分は通常、コンパイラスイートの一部として提供される別々のランタイムライブラリに組み込まれています。 GCCの場合、これはlibgomp
です。これは、OpenMP構成を簡単に実装するために使用される一連の高レベル関数を提供します。コンパイラの内部でもあり、ユーザコードで使用することを意図していません。つまり、ヘッダファイルは提供されていません。
GCCでは、OpenMP変換後のコードの擬似コード表現を得ることができます。 -fdump-tree-all
オプションを指定する必要があります。このオプションを指定すると、コンパイル単位ごとに多数の中間ファイルが生成されます。最も興味深いものはfilename.017t.ompexp
です(これはGCC 4.7.1に由来しますが、数字は他のGCCバージョンでは異なるかもしれませんが、拡張子はまだ.ompexp
です)。このファイルには、OpenMP構造体を下げてから適切な実装に展開した後のコードの中間表現が含まれています。fun.c.017t.ompexp
の含有量が
void fun(double *data, int n)
{
#pragma omp parallel for
for (int i = 0; i < n; i++)
data[i] += data[i]*data[i];
}
:
はfun.c
として保存された次のサンプルCコードは、検討
fun (double * data, int n)
{
...
struct .omp_data_s.0 .omp_data_o.1;
...
<bb 2>:
.omp_data_o.1.data = data;
.omp_data_o.1.n = n;
__builtin_GOMP_parallel_start (fun._omp_fn.0, &.omp_data_o.1, 0);
fun._omp_fn.0 (&.omp_data_o.1);
__builtin_GOMP_parallel_end();
data = .omp_data_o.1.data;
n = .omp_data_o.1.n;
return;
}
fun._omp_fn.0 (struct .omp_data_s.0 * .omp_data_i)
{
int n [value-expr: .omp_data_i->n];
double * data [value-expr: .omp_data_i->data];
...
<bb 3>:
i = 0;
D.1637 = .omp_data_i->n;
D.1638 = __builtin_omp_get_num_threads();
D.1639 = __builtin_omp_get_thread_num();
...
<bb 4>:
... this is the body of the loop ...
i = i + 1;
if (i < D.1644)
goto <bb 4>;
else
goto <bb 5>;
<bb 5>:
<bb 6>:
return;
...
}
Iは、簡潔にするため、出力の大部分を省略しています。これはまさにCコードではありません。それはプログラムフローのCのような表現です。 <bb N>
は、いわゆるベーシックブロック - プログラムのワークフローで単一ブロックとして扱われるステートメントの集合です。最初に見られるのは、並列領域が別の関数に抽出されるということです。これは珍しいことではありません。大部分のOpenMP実装は、ほぼ同じコード変換を行います。コンパイラはGOMP_parallel_start
とGOMP_parallel_end
のようなlibgomp
関数への呼び出しを挿入し、これを使ってブートストラップし、その後パラレル領域(__builtin_
という接頭辞は後で削除されます)の実行を終了します。 fun._omp_fn.0
の内部にはというループがあり、<bb 4>
に実装されています(ループ自体も展開されています)。また、すべての共有変数は、並列領域の実装に渡される特別な構造に入れられます。 <bb 3>
には、現在のスレッドが動作する反復の範囲を計算するコードが含まれています。
まあまあCコードではありませんが、これはおそらくGCCから得られる最も近いものです。
- 1. OpenMPコードをCコードにコンパイル
- 2. パラレル化:pthreadsまたはOpenMP?
- 3. Scientific Computing :: OpenMPまたはPthreads
- 4. clang-clを使用してopenmpでCコードをコンパイル
- 5. Objective-CコードをCにコンパイル
- 6. OpenMPコードC++は遅いthatn C++
- 7. R CMD SHLIBを使用してCコードをコンパイルする方法OpenMPを使用するには?
- 8. C pthreadsとシグナリング
- 9. Pthreads and Structures C++
- 10. CヘッダとCUDAコードでCコードをコンパイルするには?
- 11. RokuのC++コードをコンパイルするには?
- 12. スタティックライブラリ(.a)にC++コードをコンパイル
- 13. Cプロデューサー/コンシューマー(PThreadsを使用)
- 14. アプリケーションでC#コードをコンパイルする
- 15. getopt.h:WindowsでLinuxのCコードをコンパイルする
- 16. PythonでCコードをコンパイルするsetuptools 'bdist_deb'
- 17. fattach()でcコードをコンパイルする方法
- 18. インクルードなしでC++コードをコンパイルする
- 19. Android携帯でCコードをコンパイルする
- 20. MacでC++コードをコンパイル
- 21. c - pthreadsのグローバル変数
- 22. C++ OpenMPプログラム
- 23. openmpを使ってC++コードを並列化するのに助けが必要
- 24. 実行時にC#コード拡張をコンパイル
- 25. OpenMPでLLVM/Clangをビルド中にOpenMPとC++に関連するエラー
- 26. コンパイルC++コードにこのコードを考えるとブーストのregex_match
- 27. ARMアーキテクチャのC++コードのコンパイル
- 28. Visual StudioコードVSCodeデバッグ/コンパイルC++
- 29. Visual StudioコードでのC++コードのコンパイル
- 30. c pthreads + valgrind =メモリリーク:なぜですか?
これはありません。 'gcc -E'は前処理を行いますが、' #pragma'は解釈されません。 –