/* * * CA performance test * * History * joh 09-12-89 Initial release * joh 12-20-94 portability * * */ #include #include #include #include #include #include #include "epicsAssert.h" #include "cadef.h" #include "caProto.h" #include "tsStamp.h" #ifndef LOCAL #define LOCAL static #endif #ifndef OK #define OK 0 #endif #ifndef NULL #define NULL 0 #endif #ifndef min #define min(A,B) ((A)>(B)?(B):(A)) #endif #ifndef NELEMENTS #define NELEMENTS(A) (sizeof (A) / sizeof ((A) [0])) #endif #if defined(vxWorks) || defined(VMS) #define ITERATION_COUNT 1000 #else #define ITERATION_COUNT 10000 #endif #define WAIT_FOR_ACK typedef struct testItem { chid chix; char name[40]; int type; int count; union db_access_val val; }ti; ti itemList[ITERATION_COUNT]; enum appendNumberFlag {appendNumber, dontAppendNumber}; int catime (char *channelName, enum appendNumberFlag appNF); typedef void tf (ti *pItems, unsigned iterations, unsigned *pInlineIter); LOCAL void test ( ti *pItems, unsigned iterations ); LOCAL void printSearchStat(unsigned iterations); LOCAL tf test_pend; LOCAL tf test_search; LOCAL tf test_sync_search; LOCAL tf test_free; LOCAL tf test_wait; LOCAL tf test_put; LOCAL tf test_wait; LOCAL tf test_get; LOCAL void measure_get_latency (ti *pItems, unsigned iterations); void timeIt( tf *pfunc, ti *pItem, unsigned iterations ); #ifndef iocCore int main(int argc, char **argv) { char *pname; if(argc <= 1 || argc>3){ printf("usage: %s []\n", argv[0]); return -1; } else{ pname = argv[1]; if (argc==3) { catime(pname, appendNumber); } else { catime(pname, dontAppendNumber); } } return 0; } #endif /* * catime () */ int catime (char *channelName, enum appendNumberFlag appNF) { long i; unsigned strsize; SEVCHK (ca_task_initialize(),"Unable to initialize"); if (appNF==appendNumber) { printf("Testing with %lu channels named %snnn\n", (unsigned long) NELEMENTS(itemList), channelName); } else { printf("Testing with %lu channels named %s\n", (unsigned long) NELEMENTS(itemList), channelName); } strsize = sizeof(itemList[i].name)-1; for (i=0; ichix->retry; X += retry; XX += retry*retry; if (retry>max) { max = retry; } if (retry0.0) { printf ("Elapsed Per Item = %12.8f sec, %10.1f Items per sec", delay/(iterations*inlineIter), (iterations*inlineIter)/delay); if (pItems!=NULL) { nBytes = sizeof(caHdr) + OCT_ROUND(dbr_size[pItems[0].type]); printf(", %3.1f Mbps\n", (iterations*inlineIter*nBytes*CHAR_BIT)/(delay*1e6)); } else { printf ("\n"); } } else { printf ("Elapsed Per Item = %12.8f sec\n", delay/(iterations*inlineIter)); } } /* * test_pend() */ LOCAL void test_pend( ti *pItems, unsigned iterations, unsigned *pInlineIter ) { unsigned i; int status; for (i=0; itype, pi->count, pi->chix, &pi->val); SEVCHK (status, NULL); status = ca_array_put( pi->type, pi->count, pi->chix, &pi->val); SEVCHK (status, NULL); status = ca_array_put( pi->type, pi->count, pi->chix, &pi->val); SEVCHK (status, NULL); status = ca_array_put( pi->type, pi->count, pi->chix, &pi->val); SEVCHK (status, NULL); status = ca_array_put( pi->type, pi->count, pi->chix, &pi->val); SEVCHK (status, NULL); status = ca_array_put( pi->type, pi->count, pi->chix, &pi->val); SEVCHK (status, NULL); status = ca_array_put( pi->type, pi->count, pi->chix, &pi->val); SEVCHK (status, NULL); status = ca_array_put( pi->type, pi->count, pi->chix, &pi->val); SEVCHK (status, NULL); status = ca_array_put( pi->type, pi->count, pi->chix, &pi->val); SEVCHK (status, NULL); status = ca_array_put( pi->type, pi->count, pi->chix, &pi->val); SEVCHK (status, NULL); } #ifdef WAIT_FOR_ACK status = ca_array_get (DBR_INT, 1, pItems[0].chix, &val); SEVCHK (status, NULL); status = ca_pend_io(100.0); #endif status = ca_array_put( pItems[0].type, pItems[0].count, pItems[0].chix, &pItems[0].val); SEVCHK (status, NULL); status = ca_flush_io(); SEVCHK (status, NULL); *pInlineIter = 10; } /* * test_get () */ LOCAL void test_get( ti *pItems, unsigned iterations, unsigned *pInlineIter ) { ti *pi; int status; for (pi=pItems; pi<&pItems[iterations]; pi++) { status = ca_array_get( pi->type, pi->count, pi->chix, &pi->val); SEVCHK (status, NULL); status = ca_array_get( pi->type, pi->count, pi->chix, &pi->val); SEVCHK (status, NULL); status = ca_array_get( pi->type, pi->count, pi->chix, &pi->val); SEVCHK (status, NULL); status = ca_array_get( pi->type, pi->count, pi->chix, &pi->val); SEVCHK (status, NULL); status = ca_array_get( pi->type, pi->count, pi->chix, &pi->val); SEVCHK (status, NULL); status = ca_array_get( pi->type, pi->count, pi->chix, &pi->val); SEVCHK (status, NULL); status = ca_array_get( pi->type, pi->count, pi->chix, &pi->val); SEVCHK (status, NULL); status = ca_array_get( pi->type, pi->count, pi->chix, &pi->val); SEVCHK (status, NULL); status = ca_array_get( pi->type, pi->count, pi->chix, &pi->val); SEVCHK (status, NULL); status = ca_array_get( pi->type, pi->count, pi->chix, &pi->val); SEVCHK (status, NULL); } status = ca_pend_io(100.0); SEVCHK (status, NULL); *pInlineIter = 10; } /* * test_wait () */ LOCAL void test_wait ( ti *pItems, unsigned iterations, unsigned *pInlineIter ) { ti *pi; int status; for (pi=pItems; pi<&pItems[iterations]; pi++) { status = ca_array_get( pi->type, pi->count, pi->chix, &pi->val); SEVCHK (status, NULL); status = ca_pend_io(100.0); SEVCHK (status, NULL); } *pInlineIter = 1; } /* * measure_get_latency */ LOCAL void measure_get_latency (ti *pItems, unsigned iterations) { TS_STAMP end_time; TS_STAMP start_time; double delay; double X = 0u; double XX = 0u; double max = DBL_MIN; double min = DBL_MAX; double mean; double stdDev; ti *pi; int status; for (pi=pItems; pi<&pItems[iterations]; pi++) { tsStampGetCurrent (&start_time); status = ca_array_get (pi->type, pi->count, pi->chix, &pi->val); SEVCHK (status, NULL); status = ca_pend_io (100.0); SEVCHK (status, NULL); tsStampGetCurrent(&end_time); delay = tsStampDiffInSeconds(&end_time,&start_time); X += delay; XX += delay*delay; if (delay>max) { max = delay; } if (delay