6

私は速度が遅いので、Mathematicaモジュールをコンパイルしたい。Mathematica - BitShiftRight(またはLeft)をコンパイルするには?

testC = Compile[{{inputInt, _Integer}}, 
     Module[{outputInt, bitShift = 5}, 
     outputInt = BitShiftRight[inputInt, bitShift] 
     ] 
     , CompilationTarget -> "C", RuntimeOptions -> "Speed" 
     , CompilationOptions -> {"ExpressionOptimization" -> True, 
     "InlineCompiledFunctions" -> True, 
     "InlineExternalDefinitions" -> True} 
    ]; 

私の本当の機能は長いですが、非常にシンプルな構造を持って、リストを使用し、のみ以下の機能が含まれています:合計は、表、BITANDを、場合。すべてのコンパイルとランタイムのオプションは、私の実際の関数で役に立つかもしれませんが、この1行の抽出ではありません。私は

SetSystemOptions [ - > "CompileReportExternal" - "CompileOptions">真]を設定している

私は何が起こるかを見ることができることを確認するために、そして

CompilePrint [TESTC]

期待/このスレッドから恐れられていたよう次のような結果に

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 

を与えますhttps://mathematica.stackexchange.com/a/1101/1403 BitShiftRightはコンパイルできません。このMainEvaluateの呼び出しは、私のfunctに深刻な影響を与えますイオン。私はBitAnd、BitNot、BitOr、BitXorがある間、この種の非常に低いレベルの共通関数はコンパイルできないことに非常に驚いています! 誰もが(速い)回避策を知っていますか?私はC言語関数へのMathLink呼び出しを使用することができますが、私の目的はManipulate []でこの関数を使用し、それをスタンドアロンのcdfファイルとして展開することです。この文脈で私はMathLinkを使用できないことを理解しました。ところで、そこには扱いやすい回避策がありますか?

答えて

3

32で除算すると、コンパイラはこれをシフトとして再書込みします。 Mathematicaで直接32で割り、データがパックされていることを確認してください(Developer`ToPackedArray [])。データを前後に送信するオーバーヘッドは、おそらくC言語での計算のメリットがありません。

+0

Quotientを使用すると、外部評価者呼び出しをコンパイルするだけです(少し修正する)。簡単な例では、適切な行はoutputInt = Quotient [inputInt、2^bitShift]となります。シフトの長さが固定定数の場合は、コンパイル時に電源を入れてください(多分あなたはそのことを知っていました...)。 –

+0

@ダニエル:あなたのソリューションは私の鉛を解決します。どうも!コンパイルされたコードは 'I3 = Quotient [I0、I2]'です。私が2^5で割っただけの場合、結果を整数に変換するために結果を丸める必要があります。コンパイルコードは 'R0 = R0 * I0'' R0 = R0 * R1' 'I3 = Round [R0]'(長く、効率的ではありません)です。 – Oscar6E

関連する問題