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

async_class テンプレート・クラスの使用例

次に、インテルの C++ 非同期 I/O テンプレート・クラスの使用例を示します。float 型の配列を外部ファイルに書き込む次のコードについて考えてみます。

// float 型のデータ配列
std::vector<float>  v(10000);
 
// std::vector<float> 型のユーザー定義の new 演算子 <<
std::ofstream& operator << (std::ofstream & str, std::vector<float> & vec)
{
// ユーザー定義の出力
...
 }
...
// 出力ファイル宣言 - 標準の ofstream STL クラスのオブジェクト
std::ofstream external_file("output.txt");
...
// 出力処理
external_file << v;

次のように上記のコードを変更して、出力処理を非同期に実行します。

// STL 非同期 I/O 処理をサポートするヘッダーを追加
 
#include <aiostream.h>
...
 
std::vector<float>  v(10000); 
 
std::ofstream& operator << (std::ofstream & str, std::vector<float> & vec)
{... }
...
// 出力ファイルを async::async_class テンプレート・クラスのインスタンスとして宣言
// STL ofstream から継承した新しい型を宣言
async::async_class<std::ofstream> external_file("output.txt");
...
external_file << v;
...
// すべての非同期 I/O 処理の完了を待機するため停止
external_file.wait();
…

パフォーマンスに関する推奨事項

小さなオブジェクトでは非同期モードの使用を推奨しません。例えば、一般的な型の値を出力するループで、STL ストリームへの出力にかかる時間よりも、ほかのループ処理の実行にかかる時間のほうが短い場合、非同期モードを使用しないでください。

ただし、小さなデータの出力とループ内におけるその計算のバランスが取れる場合は、一定のパフォーマンス向上が得られます。

例えば、次のコードは外部ファイルから 2 つの行列を読み取り、ループ内で別の行列の要素を求めて、その結果を出力します。

#define ARR_LEN 900
{
  std::ifstream fA("A.txt");
  fA >> A;
  std::ifstream fB("B.txt");
  fB >> B;
  std::ofstream fC(f);
 
  for(int i=0; i< ARR_LEN; i++)
   {
    for(int j=0; j< ARR_LEN; j++)
    {
     C[i][j] = 0;
     for(int k=0; k < ARR_LEN; k++)
     C[i][j]+ = A[i][k]*B[k][j]*sin((float)(k))*cos((float)(-k))*sin((float)(k+1)
     )*cos((float)(-k-1));
     fC << C[i][j] << std::endl;
    }
   }
}

行列のサイズが大きい場合、2 つのファイルからのデータの読み取りを並列に実行することで、さらにパフォーマンスを向上できます。