2016-06-27 33 views
1

Cで入力を秒単位で、ナノ秒単位で入力する関数を書きたいと思います。秒とナノ秒をマイクロ秒に変換し、合計をマイクロ秒で返します。秒とナノ秒をマイクロ秒に変換する最速の(最適な)方法

unsigned long long get_microseconds(int seconds, unsigned long long nSeconds); 

これで変換はかなり簡単です。私は、次の使用することができ、式 -

mSeconds =秒* 1000000 + nSeconds/1000実装の最速の方法だろう何

(ナノ秒の変換精度の損失は私のタイマーは100マイクロ秒のいずれにしても最小分解能を持ち、大丈夫です)この方程式は乗算および除算演算子を使用せずに最高の精度と最小のCPUサイクル数を得ることができます。

EDIT:GNUベースでカスタム設計されたカスタムツールチェーンで実行しています。私は実際に算術演算のパフォーマンスをテストしていませんが、パフォーマンスに影響するかどうか、また改善する方法があるのか​​どうか不思議です。

+0

実行中のハードウェアは?これは実際にボトルネックになっていますか?そのパフォーマンス要件を満たすことができない単純な実装ですか? – user2357112

+0

早すぎる最適化をしないでください!ターゲット解像度でカウントするだけではない理由(タイマーが100μsの解像度の場合は100 * 1000を追加します) – Olaf

+0

どのようなDSPですか?どんな種類の算術とそれがどのように扱うことができるかを知ることは非常に重要です。 –

答えて

1

nSecondsは2 上になることはありませんならば(それはあなたがtimespecなどから「スプリットタイム」で作業しているべきではない場合 - それは10 以下でなければならない)、あなたはおそらくのために32ビット整数を使用する必要がありますがそれ。

64ビットマシン上で it's not a problem

すべてのために64ビットの整数を使用する(分割がmultiply by inverse+shiftに最適化されている)が、非常にヘビーである32ビット、コンパイラgets tricked into using a full 64 bit division routine、オン。 、少なくともx86で、

unsigned long long get_microseconds(int seconds, unsigned long nSeconds) { 
    return seconds*1000000ULL + nSeconds/1000; 
} 

このdoesn't call external routines最小に64ビットのオーバーヘッドを維持するために管理します。だから、私はするだろう。

もちろん、これらのテストは、コンパイラによって生成された実際のコードを確認する必要があるDSPで作業している場合、x86(32ビットモードでも32×32乗算命令を持ちます)で行われたテストです。

7
return Seconds*1000000 + nSeconds/1000; 

価値のあるビットシフトや他のビット操作があれば、おそらくコンパイラがそれを処理します。

+0

コンパイル時に最適化を有効にし、コンパイラに解決策を提供させる簡潔な方法。 –

+0

'Seconds * 1000000'は簡単に' int'をオーバーフローさせることができます。 「Seconds * 1000000LL」を提案してください。 – chux

1

コンパイラは可能な限り乗算をほぼ確実に最適化します。それは何ないがどうなることnSecondsがあまりにも成長できないということを念頭に置いて...あなたはおそらくそれが多少速く

return Seconds*1000000 + nSeconds/1024; /* Explicitly show the error */ 

を書いていますので、1000で割ると、「小さな損失を受け入れる」であります多くの場合、エラーが受け入れられなくなる可能性があります。

あなたが何をするにしても、試験の結果 - 実際の入力よりもスピードと正確さの両方が得られます。また、関数をマクロに変換し、呼び出しをまとめて保存することもできます。率直に言って、単純な計算では、最適化コンパイラよりも優れた小さな機会があります。

また、グローバルアルゴリズムの範囲内でこの最適化の重要性を考慮してください。この関数は実際にはits savings are worth the hassleという頻度で呼び出されていますか?

関連する問題