diff --git a/src/ca/CAref.html b/src/ca/CAref.html index 77d7b4bd7..c4cee37f8 100644 --- a/src/ca/CAref.html +++ b/src/ca/CAref.html @@ -2808,11 +2808,14 @@ additional network bandwidth and server CPU load when searching for unresolved channels.

caEventRate

-
caEventRate <PV name>
+
caEventRate <PV name> [subscription count]

Description

-

Subscribe to the specified PV and periodically log its event rate.

+

Connect to the specified PV, subscribe for monitor updates the specified +number of times (default once), and periodically log the current sampled +event rate, average event rate, and the standard deviation of the event rate +in Hertz to standard out.

ca_test

ca_test <PV name> [value to be written]
diff --git a/src/ca/caEventRate.cpp b/src/ca/caEventRate.cpp index 9af789201..4498eea36 100644 --- a/src/ca/caEventRate.cpp +++ b/src/ca/caEventRate.cpp @@ -10,6 +10,7 @@ #include #include +#include #include "cadef.h" #include "dbDefs.h" @@ -25,44 +26,69 @@ extern "C" void eventCallBack ( struct event_handler_args args ) (*pCount)++; } - /* * caEventRate () */ -void caEventRate ( const char *pName ) +void caEventRate ( const char *pName, unsigned count ) { static const double initialSamplePeriod = 1.0; static const double maxSamplePeriod = 60.0 * 60.0; + printf ( "Connecting to CA Channel \"%s\".", pName ); + fflush ( stdout ); + chid chan; int status = ca_search ( pName, &chan ); SEVCHK(status, NULL); - unsigned eventCount = 0u; - status = ca_add_event ( DBR_FLOAT, chan, eventCallBack, &eventCount, NULL); - SEVCHK ( status, __FILE__ ); - status = ca_pend_io ( 10.0 ); if ( status != ECA_NORMAL ) { fprintf ( stderr, "caEventRate: %s not found\n", pName ); return; } + printf ( " done.\n" ); + + printf ( "Subscribing %u times.", count ); + fflush ( stdout ); + + unsigned eventCount = 0u; + for ( unsigned i = 0u; i < count; i++ ) { + status = ca_add_event ( DBR_FLOAT, chan, eventCallBack, &eventCount, NULL); + SEVCHK ( status, __FILE__ ); + } + + status = ca_flush_io (); + SEVCHK ( status, __FILE__ ); + + printf ( " done.\n" ); + + printf ( "Waiting for initial value events." ); + fflush ( stdout ); + // let the first one go by - while ( eventCount < 1u ) { + while ( eventCount < count ) { status = ca_pend_event ( 0.01 ); if ( status != ECA_TIMEOUT ) { SEVCHK ( status, NULL ); } } + printf ( " done.\n" ); + double samplePeriod = initialSamplePeriod; + double X = 0.0; + double XX = 0.0; + double test = 0.0; + unsigned N = 0u; while ( true ) { unsigned nEvents, lastEventCount, curEventCount; + epicsTime begin = epicsTime::getCurrent (); lastEventCount = eventCount; status = ca_pend_event ( samplePeriod ); curEventCount = eventCount; + epicsTime end = epicsTime::getCurrent (); if ( status != ECA_TIMEOUT ) { SEVCHK ( status, NULL ); } @@ -71,11 +97,22 @@ void caEventRate ( const char *pName ) nEvents = curEventCount - lastEventCount; } else { - nEvents = ( UINT_MAX - lastEventCount ) + curEventCount +1u; + nEvents = ( UINT_MAX - lastEventCount ) + curEventCount + 1u; } - errlogPrintf ( "CA Channel \"%s\" is producing %g subscription update events per second.\n", - pName, nEvents / samplePeriod ); + N++; + + double period = end - begin; + double Hz = nEvents / period; + + X += Hz; + XX += Hz * Hz; + + double mean = X / N; + double stdDev = sqrt ( XX / N - mean * mean ); + + printf ( "CA Event Rate (Hz): current %g mean %g std dev %g\n", + Hz, mean, stdDev ); if ( samplePeriod < maxSamplePeriod ) { samplePeriod += samplePeriod; diff --git a/src/ca/caEventRateMain.cpp b/src/ca/caEventRateMain.cpp index c783ad8b5..725e66102 100644 --- a/src/ca/caEventRateMain.cpp +++ b/src/ca/caEventRateMain.cpp @@ -11,15 +11,28 @@ #include #include -void caEventRate ( const char *pName ); +void caEventRate ( const char *pName, unsigned count ); int main ( int argc, char **argv ) { - if ( argc < 2 || argc > 2 ) { - printf ( "usage: %s < PV name >\n", argv[0] ); + if ( argc < 2 || argc > 3 ) { + fprintf ( stderr, "usage: %s < PV name > [subscription count]\n", argv[0] ); + return 0; } - caEventRate ( argv[1] ); + unsigned count; + if ( argc == 3 ) { + int status = sscanf ( argv[2], " %u ", & count ); + if ( status != 1 ) { + fprintf ( stderr, "expected unsigned integer 2nd argument\n" ); + return 0; + } + } + else { + count = 1; + } + + caEventRate ( argv[1], count ); return 0; }