2013-05-29 13 views
12

浮動小数点値の除算に_mm_div_psがあります。整数乗算に_mm_mullo_epi16があります。しかし、整数除算(16ビット値)のための何かがありますか?どのように私はそのような分裂を行うことができる?SSE整数除算?

+0

十分な人々がそれを必要としないので、... –

+0

いや、それは存在しないのベクターによる整数除算。おそらく、整数除算ユニットの難しさ(およびダイスペース)とともにそれを必要とする人々が不足している可能性があります。 – Mysticial

+0

定数または変数で除算しますか? –

答えて

8

彼は8ビット、16ビット、32ビット・ワード(ただし64ビット)http://www.agner.org/optimize/#vectorclass

ルックのためにSSE/AVXと整数の除算を行うための高速なアルゴリズムが実装されていAgner霧のvectorclassを参照してください。コードについてはvectori128.hファイル、algoirthmの説明はよく書かれたマニュアルであるVectorClass.pdf

ここには、彼のマニュアルのアルゴリズムを説明する断片があります。

「整数の除算 あり整数ベクトル部門の 便利です何のx86命令セット内の命令とその拡張されず、このような命令は、彼ら が存在する場合、非常に遅くなる。したがって、ベクトルクラスライブラリが使用していますこのアルゴリズムの基本原理は、次の式で表すことができます。 a/b≈a *(2n/b)>> n この計算は、次の手順を実行します。 1.適切なものを見つけるnの値 2. 2n/bを計算する 3.丸め誤差に必要な修正を計算する 4.複数の計算を行うこの問題は、複数の数値を同じ除数で除算すると有利です。 b。被除数aの各値に対してステップ4が繰り返されている間に、ステップ1,2および3は1回だけ実行すればよい。数学的な詳細は、ファイル vectori128.hに記載されています。 (T. GranlundとPLモンゴメリーも参照してください:乗算、SIGPLANの議事録を使用して不変 整数除算を "...

編集:ファイルvectori128.hの終わり近くには、との短い除算を行う方法を示していますスカラー変数 "高速除算に使用するパラメータの計算には、 よりも時間がかかるため、同じ除数オブジェクト を複数回使用すると便利です。たとえば、符号なしの短い整数を10:

short x = 10; 
uint16_t dividends[80], quotients[80];   // numbers to work with 
Divisor_us div10(x);       // make divisor object for dividing by 10 
Vec8us temp;         // temporary vector 
for (int i = 0; i < 80; i += 8) {    // loop for 4 elements per iteration 
    temp.load(dividends+i);     // load 4 elements 
    temp /= div10;        // divide each element by 10 
    temp.store(quotients+i);     // store 4 elements 
} 

編集:ショートパンツ

#include <stdio.h> 
#include "vectorclass.h" 

int main() {  
    short numa[] = {10, 20, 30, 40, 50, 60, 70, 80}; 
    short dena[] = {10, 20, 30, 40, 50, 60, 70, 80}; 

    Vec8s num = Vec8s().load(numa); 
    Vec8s den = Vec8s().load(dena); 

    Vec4f num_low = to_float(extend_low(num)); 
    Vec4f num_high = to_float(extend_high(num)); 
    Vec4f den_low = to_float(extend_low(den)); 
    Vec4f den_high = to_float(extend_high(den)); 

    Vec4f qf_low = num_low/den_low; 
    Vec4f qf_high = num_high/den_high; 
    Vec4i q_low = truncate_to_int(qf_low); 
    Vec4i q_high = truncate_to_int(qf_high); 

    Vec8s q = compress(q_low, q_high); 
    for(int i=0; i<8; i++) { 
     printf("%d ", q[i]); 
    } printf("\n"); 
} 
+1

これは定数による除算に本当に便利です - OPは彼が変数で除算したいと言っています。解凍してフロートに変換し、フロートで除算することです。 –

+0

@PaulR、あなたのコメントに応じて編集を追加しました。 vectori128.hファイルの終わりに向かって、彼は変数を使って短絡の分割を行う方法の例を示します。整数除算はまだコード内でボトルネックになっていないので、私は細部まで進んでいません(非常に速いビットを右にシフトすることによってそれを使用しなければならなかった時代です)。 –

+0

@PaulRだから、私はこれをもっと注意深く見た。 VectorClassの高速メソッドは、スカラーだけで動作します。ベクトル/ベクトル整数除算の場合、あなたは正しいと思います。唯一の解決策は、interger vector/vectorを実行する必要がある場合、浮動小数点数に変換し、除算を行い、短絡に変換することです。私はこれを行う編集を追加しました。私はスカラー分割を行う配列にshortsを保存し、それらを戻すこともできると思います。 –