When working with very large orchestras, I’ve always missed the ability to quickly profile blocks of Csound code to test for bottlenecks. There are ways to do it using some of the timer opcodes, but that approach always felt a little cumbersome. Over the weekend I decided to throw together some utility opcodes that can be added to a .csd that will measure the average amount of time it takes to execute a blocks of code in microseconds (one millionth of a second).
Note: this is a very rudimentary way of profiling code - it only reports the time spent executing a block of code. While it can be useful in a ‘general direction’ sense, it tells us nothing about important things like call frequency or memory allocation…
cabbageProfilerStart
Opcode
This opcode sets up a profiler with a unique name, and a corresponding code block label. The unique name can be passed around to other instances of each of the profiler opcodes.
Added in Cabbage v2.9.179
Syntax
cabbageProfilerStart SName, SBlock
Initialization
-
SName
– the profiler name -
SBlock
– the profiler code block label
cabbageProfilerStop
Opcode
This will stop the profiler and record the time spent on executing a block of code.
Added in Cabbage v2.9.179
Syntax
kTime cabbageProfilerStop SName, SBlock
Initialization
-
SName
– the profiler name -
SBlock
– the profiler code block label
Performance
-
kTime
– the amount of time in microseconds spent executing the block of code.
cabbageProfilerPrint
Opcode
This will print the cumulative data from each of the profiling blocks. You need only call this opcode once per profiler, and it’s best to place in the last instrument of the processing chain.
Added in Cabbage v2.9.179
Syntax
cabbageProfilerPrint SName
Initialization
-
SName
– the profiler name
Example
instr 1
;create profile with label 'p1' and test block 'oscil'
cabbageProfilerStart "P1", "oscil"
a1 oscil 1, 100
;stop block 'oscil' test
kTime1 cabbageProfilerStop "P1", "oscil"
;add a new block 'pvs'
cabbageProfilerStart "P1", "pvs"
ifftsize = 1024
ioverlap = ifftsize / 4
iwinsize = ifftsize
iwinshape = 1
ain vco2 1, 1
fftin pvsanal ain, ifftsize, ioverlap, iwinsize, iwinshape
fftblur pvsblur fftin, 2, 4
aout pvsynth fftblur
;stop block 'oscil' test
kTime2 cabbageProfilerStop "P1", "pvs"
endin