インテル® C++ コンパイラー 14.0 ユーザー・リファレンス・ガイド

parallel_loop

プラグマに続くループ文を、それらがターゲットで実行される際に並列に実行します。このプラグマは、インテル® グラフィックス・テクノロジーにのみ適用されます。

構文

#pragma parallel_loop [clause]

引数

clause

clause (節) は次のいずれかです。

collapse

並列に実行する完全入れ子ループの for ループの最大数をコンパイラーが決定します。

collapse (n)

完全入れ子ループの外側から n 個の for ループを並列に実行します。指定する数 n は正の整数で、このプラグマに続く for ループの数以上でなければなりません。

clause を指定しない場合、または #pragma parallel_loop collapse [1] を使用する場合、外側の for ループのみ並列に実行されます。

説明

入れ子構造のループを並列化するには、このプラグマとともに offload 宣言子を使用します。完全入れ子ループを並列に実行するには、collapse 節を使用します。

ターゲットが利用できない場合、プラグマは無視され、CPU はループ反復をシリアルに実行します。CPU でループ反復を並列に実行するには、cilk_for キーワードなどの別の方法を使用します。

このプラグマに続くループ反復は cilk_for ループと同じ規則に従っていなければなりません。

次のプラグマはこのプラグマに続くループで使用できます。

次のキーワードとプラグマはこのプラグマに続くループで使用できません。

次の条件の場合はエラーが発生します。

例

次に、このプラグマを使用してインテル® グラフィックス・テクノロジーをサポートするターゲットでループを並列に実行する方法を示します。

bool CrossFade::execute_offload (int do_offload)
{
	unsigned char * inputArray1 = m_inputArray1, * inputArray2 = m_inputArray2,
	* outputArray = m_outputArray;
	int arrayWidth = m_arrayWidth, arrayHeight = m_arrayHeight, arraySize = m_arraySize;
	unsigned a1 = 256 - m_blendFactor;
	unsigned a2 = m_blendFactor;
	
	// 次のコードを指定したターゲットで実行
	#pragma offload target(gfx) if (do_offload) \
	pin(inputArray1, inputArray2, outputArray: length(arraySize))
	
	// このループを並列に実行
	#pragma parallel_loop
	for (int i=0; i<arraySize; i++)
	{
		outputArray[i] = (inputArray1[i] * a1 + inputArray2[i] * a2) >> 8;
	}

	return true;
}

次に、collapse (n) 節を使用してループ反復を分離し、完全入れ子ループをターゲットで実行する方法を示します。

bool MatmultLocalsAN::execute_offload(int do_offload)
{
	
	int m = m_height, n = m_width, k = m_common;
	float (* A)[k] = (float (*)[])m_matA;
	float (* B)[n] = (float (*)[])m_matB;
	float (* C)[n] = (float (*)[])m_matC;
	
	// 次のコードを指定したターゲットで実行
	#pragma offload target(gfx) if (do_offload) \
	pin(A: length(m*k)), pin(B: length(k*n)), pin(C: length(m*n))
	
	// 最初の 2 つのループ反復は完全入れ子ループの例。
	// 残りのループ反復はループ外部のほかの関数を呼び出す。
	// 残りのループ反復を含めると不完全入れ子ループになる。
	// 完全入れ子ループの部分を実行するには、
	// collapse 節を使用して並列に実行するループ反復を
	// 指定する。
	#pragma parallel_loop collapse(2)
	for (int r = 0; r < m; r += TILE_m)
	{
		for (int c = 0; c < n; c += TILE_n)
		{
			float atile[TILE_m][TILE_k], btile[TILE_n], ctile[TILE_m][TILE_n];
			
			#pragma unroll
			ctile[:][:] = 0.0f;

			// 残りのループ反復を含めると不完全入れ子ループに
			// なる。
			for (int t = 0; t < k; t += TILE_k)
			{
				#pragma unroll
				atile[:][:] = A[r:TILE_m][t:TILE_k];
				#pragma unroll

				for (int rc = 0; rc < TILE_k; rc++) 
				{
					btile[:] = B[t+rc][c:TILE_n];
					#pragma unroll
					for (int rt = 0; rt < TILE_m; rt++) 
					{
						ctile[rt][:] += atile[rt][rc] * btile[:];
					}
				}
			}

			#pragma unroll
			C[r:TILE_m][c:TILE_n] = ctile[:][:];
		}
	}
	return true;
}

関連情報


このヘルプトピックについてのフィードバックを送信