インテル® C++ コンパイラー 17.0 デベロッパー・ガイドおよびリファレンス

デバイス上でのみメモリーを割り当てる

このトピックは、インテル® メニー・インテグレーテッド・コア (インテル® MIC) アーキテクチャーにのみ適用されます。

インテル® MIC アーキテクチャー向けのインテルのオフロード拡張を使用する場合、#pragma offload で使用されるポインター変数の値が、オフロードプロセスによって CPU 上で変更されることはありません。 ポインター変数に格納される CPU アドレスは、インテル® MIC アーキテクチャー上の動的メモリー割り当ての追跡に使用されます。オフロード・ライブラリーは、インテル® MIC アーキテクチャー上のメモリーと関連付けられた CPU アドレスを管理し、データ転送時にそのマッピング情報を使用します。

ただし、それには、インテル® MIC アーキテクチャー上に割り当てられたメモリー範囲が、CPU 上に割り当てられたメモリー範囲と一致していなければなりません。場合によっては、必要ない CPU メモリーを割り当てなければならないことがあります。

targetptr 修飾子と preallocated 修飾子は、CPU で対応するメモリーを割り当てずに、インテル® MIC アーキテクチャーで動的メモリー割り当てを可能にします。

targetptr

targetptr 修飾子は、インテル® MIC アーキテクチャー上でのみメモリーを割り当てます。

alloc_if(1) でメモリー割り当てを行う際に targetptr 修飾子を指定すると、CPU 変数はインテル® MIC アーキテクチャー上に割り当てられたメモリーアドレスで更新されます。 この値は CPU では意味がないため、有効な CPU アドレスが割り当てられない限り、オフロードプラグマのデータ転送元/転送先としてのみ使用できます。

targetptr 修飾子は、オフロードが必須の場合のみ使用できます。 targetptr と同時に指定できるオフロード修飾子は、alignalloc です。

alloc_if 修飾子と free_if 修飾子は、インテル® MIC アーキテクチャー上でのメモリー割り当て/割り当て解除を制御し、さらにオフロードランタイムによって管理されるランタイムテーブルへ割り当てられたメモリー範囲を追加/削除します。

次の例は、#pragma offload_transfer#pragma offload、および targetptr 修飾子を使用してメモリーを割り当てます。

01 #define ALLOC  alloc_if(1) free_if(0)
02 #define REUSE  alloc_if(0) free_if(0)
03 #define FREE   alloc_if(0) free_if(1)
 
10 int* cpu_p = (int*)malloc(1000*sizeof(int));
11 __declspec(target(mic)) int* mic_p;
 
20 // targetptr を指定してインテル® MIC アーキテクチャー上にメモリーを割り当てます
21 // mic_p の値は、割り当て前は未定義、割り当て後は MIC 上のメモリーアドレスになります
22 #pragma offload_transfer target(mic) \
23   nocopy(mic_p[0:1000] : ALLOC targetptr)
 
30 // CPU からインテル® MIC アーキテクチャーへデータを転送し、処理を行います
31 #pragma offload target(mic) \
32   in(cpu_p[0:1000] : into(mic_p[0:1000]) REUSE targetptr)
33 {
34      … = *mic_p; // mic_p で指定されたデータを使用します
35     *mic_p = …   // mic_p で指定された値を更新します
36 }
 
40 // インテル® MIC アーキテクチャーから CPU へデータを転送し、メモリーを解放します
41 #pragma offload_transfer target(mic) \
42   out(mic_p[0:1000] : into(cpu_p[0:1000]) FREE targetptr)

preallocated targetptr

preallocated 修飾子と targetptr 修飾子を同時に使用してインテル® MIC アーキテクチャー上でメモリーを割り当てることができます。 これらの修飾子を使用すると、ユーザーによって割り当て済みのインテル® MIC アーキテクチャー上のメモリーがデータ転送で利用可能になります。

alloc_if 修飾子と free_if 修飾子は、オフロード・ライブラリー・テーブルへの追加/削除にのみ影響し、メモリー割り当てはプログラマーが行います。

preallocated targetptr alloc_if(1) は、in 節とともに使用することはできません。インテル® MIC アーキテクチャー上ではメモリーを割り当て済みですが、そのメモリーアドレスがまだ CPU 上でデータ転送に利用できないためです。 out 節または nocopy 節とともに使用することはできます。 オフロードの終了時に、インテル® MIC アーキテクチャー上のメモリーアドレスが CPU に送られます。CPU 上に送られた変数は、以降のオフロードでメモリーアクセスに利用できます。

次の表は、preallocated targetptrinoutinoutnocopy 節、および alloc_iffree_if 修飾子を組み合わせて使用した場合の動作の説明です。

修飾子 説明
in alloc_if(0) free_if(0)

preallocated targetptr として登録された変数にデータが転送されます。

in alloc_if(0) free_if(1)

preallocated targetptr として登録された変数にデータが転送され、オフロード後にその登録が削除されます。

in alloc_if(1) free_if(0)

許可されていません。

in alloc_if(1) free_if(1)

許可されていません。

out alloc_if(0) free_if(0)

preallocated targetptr として登録された変数にデータが転送されます。

out alloc_if(0) free_if(1)

preallocated targetptr として登録された変数からデータが転送され、オフロード後にその登録が削除されます。

out alloc_if(1) free_if(0)

オフロードの終了時に、変数が preallocated targetptr として登録され、データが転送されます。

out alloc_if(1) free_if(1)

オフロードの終了時に、変数が preallocated targetptr として登録され、その変数からデータが転送され、その後登録が削除されます。

inout alloc_if(0) free_if(0)

オフロードの開始時に preallocated targetptr として登録された変数にデータが転送され、オフロードの終了時にその変数からデータが転送されます。

inout alloc_if(0) free_if(1)

オフロードの開始時に preallocated targetptr として登録された変数にデータが転送され、オフロードの終了時にその変数からデータが転送され、登録が削除されます。

inout alloc_if(1) free_if(0)

許可されていません。

inout alloc_if(1) free_if(1)

許可されていません。

nocopy alloc_if(0) free_if(0)

データ転送または登録の変更は発生しません。

nocopy alloc_if(0) free_if(1)

データ転送は発生しません。オフロードの終了時に登録が削除されます。

nocopy alloc_if(1) free_if(0)

データ転送は発生しません。オフロードの終了時に登録が追加されます。

nocopy alloc_if(1) free_if(1)

データ転送または登録の変更は発生しません。

preallocated 修飾子は、オフロードが必須の場合のみ有効です。 オフロードがオプションの場合、メモリー割り当てを行うオフロードが実行されないと、割り当て済みメモリーを使用する以降のオフロードは失敗します。

preallocated 修飾子はプログラマーによってメモリーが割り当てられるため、align 修飾子と同時に使用することはできません。

alloc 修飾子は同時に使用することができます。

次の例は、#pragma offload#pragma offload を使用してメモリーを割り当てます。

01 // malloc を使用してインテル® MIC アーキテクチャー上にメモリーを割り当て、登録します
02 #pragma offload target(mic) \
03   nocopy(mic_p[0:1000] ALLOC preallocated targetptr )
04 {
05      mic_p = user_malloc(1000*sizeof(int));
06 }
 
10 // CPU からインテル® MIC アーキテクチャーへデータを転送し、処理を行います
11 #pragma offload target(mic) \
12   in(cpu_p[0:1000] : into(mic_p[0:1000]) REUSE targetptr )
13 {
14      = *mic_p;
15     *mic_p = …
16 }
 
20 // インテル® MIC アーキテクチャー上のメモリー登録を削除し、メモリーを解放します
21 #pragma offload target(mic) \
22   nocopy(mic_p : FREE preallocated targetptr )
23 {
24      free(mic_p);
25 }

関連情報