Intel® oneAPI DPC++/C++ Compiler Developer Guide and Reference

ID 767253
Date 9/08/2022
Public

A newer version of this document is available. Customers should click here to go to the newest version.

Document Table of Contents

Example for aio_read and aio_write Functions

The example illustrates the performance gain of the asynchronous I/O usage in comparison with synchronous I/O usage. In the example, 5.6 MB of data is asynchronously written with the main program computation, which is the scalar multiplication of two vectors with some normalization.

С-source File Executing a Scalar Multiplication

#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; }

C-main-source File Using Asynchronous I/O Implementation (Example One)

#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); /* Do some complex computation */ 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; }

C-main-source File Using Asynchronous I/O Implementation (Example Two)

// icx -c do_compute.c // icx 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; /* ** writing */ 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();} } // // flushing // printf("Flushing\n"); WAIT; res = aio_fsync(O_SYNC, &my_aio); if (res) {printf("res!=0\n");abort();} WAIT; // // reading // 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; }