void run_max_io(char *dev, uint32_t vlen, uint32_t LEN) { ARK *ark[MAX_IO_ARKS]; worker_t w[MAX_IO_ARKS][MAX_IO_PTHS]; uint32_t i = 0; uint32_t j = 0; uint32_t ops = 0; uint32_t ios = 0; uint32_t tops = 0; uint32_t tios = 0; uint32_t e_secs = 0; init_kv_db(MAX_IO_PTHS, KLEN, vlen, LEN); testcase_start = time(0); for (i=0; i<MAX_IO_ARKS; i++) { NEW_ARK(dev, &ark[i]); /* create all threads */ for (j=0; j<MAX_IO_PTHS; j++) { w[i][j].ark = ark[i]; w[i][j].db = dbs+(j % KV_PTHS); pthread_create(&(w[i][j].pth), NULL, fp, (void*)(&w[i][j])); } } /* wait for all threads to complete */ for (i=0; i<MAX_IO_ARKS; i++) { for (j=0; j<MAX_IO_PTHS; j++) { pthread_join(w[i][j].pth, NULL); } } testcase_stop = time(0); for (i=0; i<MAX_IO_ARKS; i++) { get_stats(ark[i], &ops, &ios); tops += ops; tios += ios; } e_secs = testcase_stop - testcase_start; ops = tops / e_secs; ios = tios / e_secs; printf("op/s:%7d io/s:%7d secs:%d\n", ops, ios, e_secs); free_kv_db(MAX_IO_PTHS, LEN); for (i=0; i<MAX_IO_ARKS; i++) { assert(0 == ark_delete(ark[i])); } }
/** ******************************************************************************** ** \brief ** create threads to run one of the IO functions, wait for the threads to ** complete, and print the iops *******************************************************************************/ void kv_sync_io(char *dev, uint32_t vlen, uint32_t len, uint32_t pths, uint32_t read) { worker_t w[KV_PTHS]; ARK *ark = NULL; uint32_t i = 0; uint32_t ops = 0; uint32_t ios = 0; uint32_t e_secs = 0; char *fp_txt = NULL; void* (*fp)(void*); if (read == 75) { fp = (void*(*)(void*))read_75_percent; fp_txt="read: 75%"; } else { fp = (void*(*)(void*))read_100_percent; fp_txt="read:100%"; } init_kv_db(pths, KLEN, vlen, len); NEW_ARK(dev, &ark); printf("SYNC: ctxt:%-2d QD:%-3d size:%2dk %s ", 1, pths, vlen/1000,fp_txt); fflush(stdout); testcase_start = time(0); /* start all threads */ for (i=0; i<pths; i++) { w[i].ark = ark; w[i].db = dbs+(i % pths); pthread_create(&(w[i].pth), NULL, fp, (void*)(w+i)); } /* wait for all threads to complete */ for (i=0; i<pths; i++) { pthread_join(w[i].pth, NULL); } testcase_stop = time(0); e_secs = testcase_stop - testcase_start; get_stats(ark, &ops, &ios); ops = ops / e_secs; ios = ios / e_secs; printf("op/s:%-7d io/s:%-7d secs:%d\n", ops, ios, e_secs); free_kv_db(pths, len); assert(0 == ark_delete(ark)); }
/** ******************************************************************************** ** \brief ** create max arks, create max threads to run one of the IO functions, wait ** for the threads to complete, prints the iops, delete the arks *******************************************************************************/ void kv_max_sync_io(char *dev, uint32_t vlen, uint32_t len) { ARK *ark[MAX_IO_ARKS]; worker_t w[MAX_IO_ARKS][MAX_IO_PTHS]; uint32_t i = 0; uint32_t j = 0; uint32_t ops = 0; uint32_t ios = 0; uint32_t tops = 0; uint32_t tios = 0; uint32_t e_secs = 0; printf("SYNC: ctxt:%-2d QD:%-3d size: 4k read:100%% ", MAX_IO_ARKS, MAX_IO_PTHS); fflush(stdout); init_kv_db(MAX_IO_PTHS, KLEN, vlen, len); for (i=0; i<MAX_IO_ARKS; i++) { NEW_ARK(dev, ark+i); } testcase_start = time(0); for (i=0; i<MAX_IO_ARKS; i++) { /* create all threads */ for (j=0; j<MAX_IO_PTHS; j++) { w[i][j].ark = ark[i]; w[i][j].db = dbs+(j % KV_PTHS); pthread_create(&(w[i][j].pth), NULL, (void*(*)(void*))read_100_percent, (void*)(&w[i][j])); } } /* wait for all threads to complete */ for (i=0; i<MAX_IO_ARKS; i++) { for (j=0; j<MAX_IO_PTHS; j++) { pthread_join(w[i][j].pth, NULL); } } testcase_stop = time(0); for (i=0; i<MAX_IO_ARKS; i++) { get_stats(ark[i], &ops, &ios); tops += ops; tios += ios; } e_secs = testcase_stop - testcase_start; ops = tops / e_secs; ios = tios / e_secs; printf("op/s:%-7d io/s:%-7d secs:%d\n", ops, ios, e_secs); free_kv_db(MAX_IO_PTHS, len); for (i=0; i<MAX_IO_ARKS; i++) { assert(0 == ark_delete(ark[i])); } }
/** ******************************************************************************** ** \brief ** do an ark asynchronous IO performance run *******************************************************************************/ void kv_async_io(char *dev, uint32_t ctxts, uint32_t jobs, uint32_t vlen, uint32_t len, uint32_t read) { async_context_t *pCT = NULL; async_CB_t *pCB = NULL; uint32_t job = 0; uint32_t ctxt = 0; uint32_t ctxt_running = 0; uint32_t i = 0; uint32_t e_secs = 0; uint64_t ops = 0; uint64_t ios = 0; uint32_t tops = 0; uint32_t tios = 0; if (read == 75) read100 = FALSE; else read100 = TRUE; printf("ASYNC: ctxt:%-2d QD:%-3d size:%2dk read:%3d%% ", ctxts, jobs, vlen/1000, read); fflush(stdout); init_kv_db(jobs, KLEN, vlen, len); pCTs = (async_context_t*) malloc(ctxts*sizeof(async_context_t)); assert(0 != pCTs); for (ctxt=0; ctxt<ctxts; ctxt++) { ARK *ark = NULL; pCT = pCTs+ctxt; memset(pCT, 0, sizeof(async_context_t)); NEW_ARK(dev, &ark); pCT->ark = ark; for (job=0; job<jobs; job++) { pCB = pCT->pCBs+job; pCB->itag = SET_ITAG(ctxt,job); pCB->ark = pCT->ark; pCB->flags = KV_ASYNC_SET; pCB->db = dbs+job; pCB->len = len; } } testcase_start = time(0); /* start all jobs for all contexts */ for (ctxt=0; ctxt<ctxts; ctxt++) { for (pCB=pCTs[ctxt].pCBs; pCB<pCTs[ctxt].pCBs+jobs; pCB++) { pCB->flags |= KV_ASYNC_RUNNING; kv_async_SET_KEY(pCB); } } /* loop until all jobs are done or until time elapses */ do { ctxt_running = FALSE; /* loop through contexts(arks) and check if all jobs are done or * time has elapsed */ for (i=0; i<ctxts; i++) { /* check if all jobs are done */ for (pCB=pCTs[i].pCBs;pCB<pCTs[i].pCBs+jobs;pCB++) { if (pCB->flags & KV_ASYNC_RUNNING) { ctxt_running = TRUE; } } if (!ctxt_running) continue; /* check if time has elapsed */ if (time(0) - testcase_start < KV_MIN_SECS) continue; for (pCB=pCTs[i].pCBs;pCB<pCTs[i].pCBs+jobs;pCB++) { if (pCB->flags & KV_ASYNC_RUNNING && (!(pCB->flags & KV_ASYNC_SHUTDOWN)) ) { pCB->flags |= KV_ASYNC_SHUTDOWN; } } } } while (ctxt_running); testcase_stop = time(0); e_secs = testcase_stop - testcase_start; /* sum perf ops for all contexts/jobs and delete arks */ for (i=0; i<ctxts; i++) { (void)ark_stats(pCTs[i].ark, &ops, &ios); tops += (uint32_t)ops; tios += (uint32_t)ios; } tops = tops / e_secs; tios = tios / e_secs; printf("op/s:%-7d io/s:%-7d secs:%d\n", tops, tios, e_secs); /* sum perf ops for all contexts/jobs and delete arks */ for (i=0; i<ctxts; i++) { assert(0 == ark_delete(pCTs[i].ark)); } free_kv_db(jobs, len); }
int main(int argc, char **argv) { ARK *ark; int i=1; if (argv[1] == NULL) { printf("dev name required as parameter\n"); exit(-1); } if (0 == strncmp(argv[1], "-p", 7)) { printf("Attempting to run with physical lun\n"); ark_create_flag = ARK_KV_PERSIST_STORE; i = 2; } printf("%s: SYNC: npool:%d nasync:%d basync:%d\n", argv[i], KV_NPOOL, KV_NASYNC, KV_BASYNC); fflush(stdout); /* 1 ctxt, vlen 4k */ init_kv_db(KV_PTHS, KLEN, VLEN_4k, LEN_4k); NEW_ARK(argv[i], &ark); printf("ctxt:1 4k-k/v: 75%% read: "); fflush(stdout); fp = (void*(*)(void*))do_75_percent_read; run_io(ark, KV_PTHS); free_kv_db(KV_PTHS, LEN_4k); assert(0 == ark_delete(ark)); /* 1 ctxt, vlen 4k */ init_kv_db(KV_PTHS, KLEN, VLEN_4k, LEN_4k); NEW_ARK(argv[i], &ark); printf("ctxt:1 4k-k/v: 100%% read: "); fflush(stdout); fp = (void*(*)(void*))do_100_percent_read; run_io(ark, KV_PTHS); free_kv_db(KV_PTHS, LEN_4k); assert(0 == ark_delete(ark)); /* 1 ctxt, vlen 64k */ init_kv_db(KV_PTHS_BIG, KLEN, VLEN_64k, LEN_BIG); NEW_ARK(argv[i], &ark); printf("ctxt:1 64k-k/v: 100%% read: "); fflush(stdout); fp = (void*(*)(void*))do_100_percent_read; run_io(ark, KV_PTHS_BIG); free_kv_db(KV_PTHS_BIG, LEN_BIG); assert(0 == ark_delete(ark)); /* 1 ctxt, vlen 1mb */ init_kv_db(KV_PTHS_BIG, KLEN, VLEN_500k, LEN_BIG); NEW_ARK(argv[i], &ark); printf("ctxt:1 500k-k/v: 100%% read: "); fflush(stdout); fp = (void*(*)(void*))do_100_percent_read; run_io(ark, KV_PTHS_BIG); free_kv_db(KV_PTHS_BIG, LEN_BIG); assert(0 == ark_delete(ark)); /* if physical lun, cannot run multi-context, so exit */ if (ARK_KV_PERSIST_STORE == ark_create_flag) return 0; printf("ctxt:4 4k-k/v: 100%% read: "); fflush(stdout); fp = (void*(*)(void*))do_100_percent_read; run_max_io(argv[i], VLEN_4k, LEN_4k); printf("ctxt:4 64k-k/v: 100%% read: "); fflush(stdout); fp = (void*(*)(void*))do_100_percent_read; run_max_io(argv[i], VLEN_64k, LEN_BIG); return 0; }