インテル® C++ コンパイラー 17.0 デベロッパー・ガイドおよびリファレンス
ここでは、非同期 I/O を使用した場合と同期 I/O を使用した場合のパフォーマンスの違いを示します。 次の例は、メインプログラムで 2 つのベクトルのスカラー乗算を正規化し、5.6 MB のデータを非同期に書き込みます。
スカラー乗算を実行する C ソースファイル:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
double do_compute(double A, double B, int arr_len)
{
int i;
double res = 0;
double *xA = malloc(arr_len * sizeof(double));
double *xB = malloc(arr_len * sizeof(double));
if ( !xA || !xB )
abort();
for (i = 0; i < arr_len; i++) {
xA[i] = sin(A);
xB[i] = cos(B);
res = res + xA[i]*xA[i];
}
free(xA);
free(xB);
return res;
}
非同期 I/O を使用する C メイン・ソース・ファイル:
#define DIM_X 123/*123*/
#define DIM_Y 70000
double aio_dat[DIM_Y /*12MB*/] = {0};
double aio_dat_tmp[DIM_Y /*12MB*/];
#include <stdio.h>
#include <aio.h>
typedef struct aiocb aiocb_t;
aiocb_t my_aio;
aiocb_t *my_aio_list[1] = {&my_aio};
int main()
{
double do_compute(double A, double B, int arr_len);
int i, j;
HANDLE fd = CreateFile("aio.dat",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
/* 複雑な計算を実行します */
for (i = 0; i < DIM_X; i++) {
for ( j = 0; j < DIM_Y; j++ )
aio_dat[j] = do_compute(i, j, DIM_X);
if (i) aio_suspend(my_aio_list, 1, 0);
my_aio.aio_fildes = fd;
my_aio.aio_buf = memcpy(aio_dat_tmp, aio_dat, sizeof(aio_dat_tmp));
my_aio.aio_nbytes = sizeof(aio_dat_tmp);
my_aio.aio_offset = (intptr_t)-1;
my_aio.aio_sigevent.sigev_notify = SIGEV_NONE;
if ( aio_write((void*)&my_aio) == -1 ) {
printf("ERROR!!! %s\n", "aio_write()==-1");
abort();}
}
aio_suspend(my_aio_list, 1, 0);
return 0;
}
非同期 I/O を使用する C メイン・ソース・ファイル例 2:
// icl -c do_compute.c
// icl aio_sample2.c do_compute.obj
// aio_sample2.exe
#define DIM_X 123
#define DIM_Y 70
double aio_dat[DIM_Y] = {0};
double aio_dat_tmp[DIM_Y];
static volatile int aio_flg = 1;
#include <aio.h>
typedef struct aiocb aiocb_t;
aiocb_t my_aio;
#define WAIT { while (!aio_flg); aio_flg = 0; }
#define aio_OPEN(_fname )\
CreateFile(_fname, \
GENERIC_READ | GENERIC_WRITE, \
FILE_SHARE_READ, \
NULL, \
OPEN_ALWAYS, \
FILE_ATTRIBUTE_NORMAL, \
NULL)
static void aio_CompletionRoutine(sigval_t sigval)
{
aio_flg = 1;
}
int main()
{
double do_compute(double A, double B, int arr_len);
int i, j, res;
char *fname = "aio_sample2.dat";
HANDLE aio_fildes = aio_OPEN(fname);
my_aio.aio_fildes = aio_fildes;
my_aio.aio_nbytes = sizeof(aio_dat_tmp);
my_aio.aio_sigevent.sigev_notify = SIGEV_THREAD;
my_aio.aio_sigevent.sigev_notify_function = aio_CompletionRoutine;
/*
** 書き込み中
*/
my_aio.aio_offset = -1;
printf("Writing\n");
for (i = 0; i < DIM_X; i++) {
for (j = 0; j < DIM_Y; j++)
aio_dat[j] = do_compute(i, j, DIM_X);
WAIT;
my_aio.aio_buf = memcpy(aio_dat_tmp, aio_dat, sizeof(aio_dat_tmp));
res = aio_write(&my_aio);
if (res) {printf("res!=0\n");abort();}
}
//
// フラッシュ中
//
printf("Flushing\n");
WAIT;
res = aio_fsync(O_SYNC, &my_aio);
if (res) {printf("res!=0\n");abort();}
WAIT;
//
// 読み取り中
//
printf("Reading\n");
my_aio.aio_offset = 0;
my_aio.aio_buf = (volatile char*)aio_dat_tmp;
for (i = 0; i < DIM_X; i++) {
aio_read(&my_aio);
for (j = 0; j < DIM_Y; j++)
aio_dat[j] = do_compute(i, j, DIM_X);
WAIT;
res = aio_return(&my_aio);
if (res != sizeof(aio_dat)) {
printf("aio_read() did read %d bytes, expecting %d bytes\n", res, sizeof(aio_dat));
}
for (j = 0; j < DIM_Y; j++)
if ( aio_dat[j] != aio_dat_tmp[j] )
{printf("ERROR: aio_dat[j] != aio_dat_tmp[j]\n I=%d J=%d\n", i, j); abort();}
my_aio.aio_offset += my_aio.aio_nbytes;
}
CloseHandle(aio_fildes);
printf("\nDone\n");
return 0;
}