Ich möchte ein Mathematica-Modul kompilieren, weil ich nach Geschwindigkeit bin.Mathematica - Wie BitShiftRight (oder Links) zu kompilieren?
testC = Compile[{{inputInt, _Integer}},
Module[{outputInt, bitShift = 5},
outputInt = BitShiftRight[inputInt, bitShift]
]
, CompilationTarget -> "C", RuntimeOptions -> "Speed"
, CompilationOptions -> {"ExpressionOptimization" -> True,
"InlineCompiledFunctions" -> True,
"InlineExternalDefinitions" -> True}
];
Meine eigentliche Funktion ist länger, aber hat eine sehr einfache Struktur verwendet Listen und enthält folgende Funktion: Gesamt, Tisch, BitAnd, If. Alle Kompilierungs- und Laufzeitoptionen sind (vielleicht) in meiner echten Funktion nützlich, nicht in diesem Ein-Zeilen-Extrakt.
Ich habe gesetzt
SetSystemOptions [ "CompileOptions" -> "CompileReportExternal" -> True];
um sicherzustellen, dass ich sehen kann, was passiert, und
CompilePrint [TestC]
ergibt folgendes Ergebnis
1 argument
3 Integer registers
Underflow checking off
Overflow checking off
Integer overflow checking off
RuntimeAttributes -> {}
I0 = A1
I1 = 5
Result = I2
1 I2 = MainEvaluate[ Hold[BitShiftRight][ I0, I1]]
2 Return
As/aus diesem Thread befürchteten erwartet https://mathematica.stackexchange.com/a/1101/1403 BitShiftRight ist nicht kompilierbar, und dieser Aufruf von MainEvaluate ist eine ernsthafte Beeinträchtigung meiner Funktion Ion. Ich bin extrem überrascht, dass diese Art von sehr niedriger Ebene, gemeinsame Funktion nicht kompilierbar ist, während BitAnd, BitNot, BitOr, BitXor sind! Kennt jemand einen (schnellen) Workaround? Ich kann einen MathLink-Aufruf für eine C-Sprachenfunktion verwenden, aber mein Ziel ist es, diese Funktion in einem Manipulate [] zu verwenden und es als eigenständige cdf-Datei bereitzustellen. Und ich verstehe, dass ich in diesem Zusammenhang MathLink nicht verwenden kann, richtig? Übrigens, gibt es da eine handliche Abhilfe?
Nur zur Bestätigung (und geringfügigen Änderung), wenn Sie Quotient verwenden, kompiliert es keine externen Evaluator-Aufrufe. In dem einfachen Beispiel wäre die entsprechende Zeile outputInt = Quotient [inputInt, 2^bitShift]]. Wenn Ihre Schichtlänge eine feste Konstante ist, sollte das Einschalten zur Kompilierungszeit erfolgen (wahrscheinlich wussten Sie beide, dass ...). –
@Daniel: Deine Lösung löst meinen Pb. Danke! Dann lautet der kompilierte Code "I3 = Quotient [I0, I2]". Wenn ich nur durch 2^5 dividiere, muss ich [] mit dem Ergebnis runden, um es in einen Integer umzuwandeln. Dann lautet der Kompiliercode "R1 = Wechselseitig [R0] " 'R0 = I0'' R0 = R0 * R1 ''I3 = Runde [R0]' (länger, weniger effizient). – Oscar6E