There is example in Mathematica documentation about Compile
cf = Compile[{{x}}, Sin[x]];
cf5 = Compile[ {{x}}, cf[x^2],
CompilationOptions -> {"InlineExternalDefinitions" -> True,
"InlineCompiledFunctions" -> False}];
The above code makes "InlineCompiledFunctions"
False
, thus prevents inlining. If we looks at the CompilePrint
output,
<<CompiledFunctionTools`
CompilePrint[cf5]
will be
1 argument
3 Real registers
Underflow checking off
Overflow checking off
Integer overflow checking on
RuntimeAttributes -> {}
R0 = A1
Result = R2
1 R1 = Square[ R0]
2 R2 = CompiledFunctionCall[ Hold[CompiledFunction[{x}, Sin[x], -CompiledCode-]][ R1]]
3 Return
There is a CompiledFunctionCall
opcode. I don't know whether this call is as efficient as the "inline" version or not. The documentation didn't say.
I quote a paragraph here which I don't quite understand.
Here the external definition is used, but the compiled function is not inlined. Instead it uses an efficient instruction to allow one compiled function to call another. This type of call is important since it could allow a compiled function to call itself, and when parallel execution is carried out in the compiler the call can be done without any synchronization locking.
What does it mean? It says "it could allow a compiled function to call itself". But there is a example in the same documentation where the compiled function is a recursive call. For example,
cFact = Compile[{{x, _Integer}}, If[x == 1, 1, x*cFact[x - 1]],
{{_cFact, _Integer}},
CompilationOptions -> {"InlineExternalDefinitions" -> True}];
CompilePrint[cFact]
And what is "synchronization locking"?