Misusing FunctionProfiling for code coverage

Posts: 507
Joined: 2009-10-07
Location: Germany

I'm trying to get code coverage information for my igor code. The end result I would like to get is a very slim version of [1].

The idea is that it is easy to see with code coverage which parts of a function have tests associated with them and which not.

I've tried using the FunctionProfiling code a la

#include <FunctionProfiling>
Function MyTest()
	variable a
		a += 1
		a += 2
Function run()
	variable i
	BeginFunctionProfiling(testTime = 1)
	for(i = 0; i < 1000000; i += 1)
 	FuncProfilingModule#EndFunctionProfiling(normMode = 0, maxPct = 100)

which gives

Function: UTF_Main.ipf MyTest; Percent total 48%
[17]** |Function MyTest()
[00] |
[00] | variable a
[03]* | if(a)
[00] | a += 1
[03]* | else
[22]** | a += 2
[03]* | endif
[00] |
[01]* |End

In principle this holds the information I want (the if branch is not executed but the else part is). The main drawbacks here are that I don't know how often I have to repeat it to get reasonable results (1e6 is already ridiculously large) and that it does seem not so reliable ("variable a" is never executed).

Is there something obvious I'm missing? Or does the Igor compiler not work how I seem to expect it?


[1]: http://ltp.sourceforge.net/coverage/lcov/output/example/methods/iterate....

JimProuty's picture
Posts: 619
Joined: 2007-07-19
Location: United States

Variables' default value is 0, so there's that (Strings' default value is NULL)

The profiling code runs in a separate thread that only periodically samples where the main thread's "program counter" is.

If the code being profiled runs very quickly, like your code does, too few samples are taken to create meaningful statistics.

The sampling interval is computed in StartProfiling():

Static Function StartProfiling(s, tmax)
	STRUCT MyProfilingStuff &s
	Variable tmax	// time in seconds the test is expected to take (needed if > 100)
	Variable desiredSamps= 100000						// big enough for 100 sec at 1ms sampling rate
	Variable tms= round(1000*tmax/desiredSamps)		// milliseconds to sleep between samples
	if( tms<1 )
		tms= 1
	elseif( tms>100 )
		tms= 100
		desiredSamps= round(tmax*1000/tms)
	Make/O/D/FREE/N=(desiredSamps) s.w
	s.tid= ThreadGroupCreate(1)
	ThreadStart s.tid, 0, DoProfiling(s.w, tms)
	s.testTime= StopMSTimer(-2)

You can see that the minimum sampling rate is 1 millisecond. run() with the loop max set to 1000000 runs in 16.4576 microseconds.

--Jim Prouty
Software Engineer, WaveMetrics, Inc.

[ last edited September 12, 2017 - 12:07 ]

Back to top