/* This header declares MeasureNetTimeInCPUCycles, which measures the execution time of a routine. Comments below describe the driver routine that must be passed to MeasureNetTimeInCPUCyles and the other parameters to MeasureNetTimeInCPUCycles. Written by Eric Postpischil, Apple, Inc. */ #if !defined(apple_com_Accelerate_ClockServices_h) #define apple_com_Accelerate_ClockServices_h #if defined(__cplusplus) extern "C" { #endif /* Define a type describing a routine whose performance will be measured. The routine must take a parameter which is the number of iterations to execute and another parameter which is a pointer to any type of data. To time any routine, write a small driver routine. For example: struct MyParameters { int Argument0; float *Argument1; double Argument2; }; void MyDriver(unsigned int iterations, void *data) { struct MyParameters *p = (struct MyParameters *) data; while (--iterations) MyRoutine(p->Argument0, p->Argument1, p->Argument2); } Then use MyDriver as the routine to be measured. */ typedef void (*RoutineToBeTimedType)(unsigned int iterations, void *data); /* MeasureNetTimeInCPUCycles. This routine measures the net amount of time it takes to execute an arbitrary routine. The net time excludes overhead such as reading the clock value and loading the routine into cache. The time for multiple iterations (and multiple samples, see below) is measured. This time is divided to return the time for a single iteration. Input: RoutineToBeTimedType routine. Address of a routine to measure. (See typedef for this type, above.) unsigned int iterations. Number of iterations to be measured. void *data. Pointer to be passed to the routine. unsigned int samples. Number of samples to take. The time a routine takes to perform varies due to many factors, so multiple samples are taken in an attempt to find the "true" time taken by the routine itself. On Mac OS X, the largest variance is often due to interrupts or process context switching. There is no good way to exclude these or filter them out. When interrupts occur, a routine takes longer than is required for the routine alone. Thus, the minimum time observed in the samples may be the time the routine takes if no interrupts occur. By itself, this could produce an incorrectly low time. For example, we might happen to start measuring just after a clock tick and stop just before a clock tick. However, some fine-grain clocks are available, so the size of a clock tick should not bias the measurement too much. Also, the measuring routine makes a control measurement the same way. When N iterations are requested, MeasureNetTime measures the subject routine for 2 iterations and for N+2 iterations. Factors that may make one measurement too low may also make the other measurement too low. The measuring routine returns the difference, so errors should cancel to some extent. Output: Return value. Number of CPU cycles to execute one iteration. */ double MeasureNetTimeInCPUCycles( RoutineToBeTimedType routine, unsigned int iterations, void *data, unsigned int samples ); #if defined(__cplusplus) } // extern "C" #endif #endif // !defined(apple_com_Accelerate_ClockServices_h)