2011-01-22 16 views
3


私が現在取り組んでいるプロジェクトでは、要素を挿入できるソート済みの配列(たとえば、C++のstd :: lower_bound) 。 SSEを使用して私のアルゴリズムを高速化するのはかなり魅力的なようですが、uint32の配列はプロセッサのキャッシュラインのサイズと同じサイズです。 私はこれまでSSE命令を使ったことがないので、この関数のSSE実装がどのように見えるかわかりません。 SSEに合わせて最適に書くためのヒントを教えてください。SSEを使用してlower_bound関数を高速化する

+0

時間をかけて研究をしてください。次にそれについて考えて、おそらくそれがどのように機能するかの「感じ」を得るためにいくつかのことを試してみてください。それから、より直接的な質問をしてください。質問はありません。 –

+0

32ビットのオペランドと4 32ビットのパックド整数を比較するpcmpledが見つかりましたが、この命令の結果を得る方法を見つけることができません。たぶん、この命令(または対応する組み込み関数)を使用する方法についての良いリファレンスを指摘できますか? – fokenrute

+0

私は間違っていたようです。 pcmpledは、32ビット整数の2つのvector4を比較し、比較結果に応じてvec4に0と1を入力します。私のために悪用するものはありません。ビリーONealのように思える、SSEは私のために役に立たないだろう。 – fokenrute

答えて

9

std::lower_boundのようなものは、SSEを使用するとうまくスケールされません。 SSEが高速化する理由は、一度に複数の計算を行うことができるからです。たとえば、SSE命令を1つ実行すると、4回の乗算が同時に実行される可能性があります。ただし、アルゴリズムの各ステップで前の手順の比較結果が必要なため、std::lower_boundの動作は並列化できません。さらに、すでにO(lg n)であり、結果としてボトルネックになることはありません。

さらに、インラインアセンブリに移動する前に、インラインアセンブリを使用するたびに、プログラムのそのセクションで発生する可能性のあるコンパイラ最適化のほとんどを無効にし、結果としてプログラムがより遅いコンパイラ通常、人間よりも優れたアセンブラを書く。

intrinsics - SSE命令を呼び出すコンパイラが提供する特殊な "関数"またはキーワードを使用すると、最適化を実行できるようになります。このような組み込み関数は、Microsoft's Visual C++およびGNU Compiler Collectionで利用できます。

SSEを使用してstd::lower_boundをスピードアップしようとするのではなく、最初に呼び出す必要はありません。たとえば、ベクトルにlower_boundを使用して要素を常に挿入している場合は、効果的に作成した内容がinsertion sortであり、それでは挿入のソートが悪いことがわかるはずです。ベクトルの最後に新しい要素を置き、並べ替えが必要なときにベクトルを並べ替えるほうが、O(ng n)のソートになります。データアクセスパターンがあまりにも頻繁に使用されるような場合は、代わりに現在O(n + lg n)個の挿入ではなく、O(lg n)個の操作を提供するstd::setのようなものを使用する必要がありますベクトルを得る。

もちろん、ベンチマークを覚えておいてください。

関連する問題