複数の非同期関数を連続して呼び出した場合、内部で開始される GPU 処理はその呼び出しが行われた順番にシリアル化されます。
その為 通常では、呼び出す関数が非同期であるか否かを意識する必要はありません。
ただし非同期関数の処理時間を計測するような場合には、非同期関数の呼び出し前と呼び出し後のタイムスタンプを単純に 比較したのでは正確な処理時間を得ることが出来ないことに注意して下さい。
このような場合には fnFGA_synchronize() を用いて非同期関数の処理完了を待って下さい。
// サンプルである為、エラー処理等は省略していることに注意して下さい. // またここでは時間取得の為に C 標準ライブラリ clock() を使用していますが、 // 実際に時間取得を行う際にはその環境で用意されているより精度の高い方法を // 使用して下さい。 #include <time.h> #include "fie.h" #include "fga.h" // === 間違った処理時間の計測例. === DOUBLE BAD_TimeCounter( FHANDLE src_FGA, FHANDLE dst_FGA ) { clock_t start, end; // 開始時間取得. start = clock(); // 計測対象となる処理の実行. fnFGA_average( src_FGA, dst_FGA, F_BORDER_NONE, 0 ); // 終了時間取得. // しかし、fnFGA_average() は非同期関数である為、内部で GPU 処理を開始させた直後に制御を返す. // おそらくこの時点で GPU 処理は完了しておらず、正しい処理時間は得られない. end = clock(); return (DOUBLE)(end - start) / CLOCKS_PER_SEC; } // === 正しい処理時間の計測例. (その 1). === DOUBLE GOOD_TimeCounter_1( FHANDLE src_FGA, FHANDLE dst_FGA ) { clock_t start, end; // 他の GPU 処理が完了するのを待つ. fnFGA_synchronize(); // 開始時間取得. start = clock(); // 計測対象となる処理の実行. fnFGA_average( src_FGA, dst_FGA, F_BORDER_NONE, 0 ); // 非同期関数 fnFGA_average() 内部での GPU 処理が完了するのを待つ. fnFGA_synchronize(); // 終了時間取得. end = clock(); return (DOUBLE)(end - start) / CLOCKS_PER_SEC; } // === 正しい処理時間の計測例. (その 2). === DOUBLE GOOD_TimeCounter_2( FHANDLE src_FGA ) { clock_t start, end; DOUBLE ave; // 他の GPU 処理が完了するのを待つ. fnFGA_synchronize(); // 開始時間取得. start = clock(); // 計測対象となる処理の実行. fnFGA_img_calc_average( src_FGA, &ave ); // 終了時間取得. // fnFGA_img_calc_average() は非同期関数ではない為、処理が完全に完了した後で制御を返す. // その為、ここでは fnFGA_synchronize() による同期を行う必要はない. end = clock(); return (DOUBLE)(end - start) / CLOCKS_PER_SEC; } VOID TimeCounter( VOID ) { FHANDLE src_FGA = NULL; FHANDLE dst_FGA = NULL; INT width = 4096, height = 4096; DOUBLE time; src_FGA = fnFGA_img_root_alloc( F_IMG_UC8, 1, width, height ); dst_FGA = fnFGA_img_root_alloc( F_IMG_UC8, 1, width, height ); // 間違った処理時間の計測例. time = BAD_TimeCounter( src_FGA, dst_FGA ); // 正しい処理時間の計測例. (その 1). time = GOOD_TimeCounter_1( src_FGA, dst_FGA ); // 正しい処理時間の計測例. (その 2). time = GOOD_TimeCounter_2( src_FGA ); fnFIE_free_object( src_FGA ); fnFIE_free_object( dst_FGA ); }