SSEを利用した差分の総和の求め方

このQ&Aのポイント
  • SSEを利用した差分の総和を求める方法を教えてください。
  • 8bit符号なし整数列を32bit符号付き整数列に変換し、SSD(2乗誤差の総和)を求めたいです。
  • 8bit→32bit→差分→乗算→総和の計算手順を効率的に行う方法を教えてください。
回答を見る
  • ベストアンサー

SSEを利用した差分の総和の求め方

現在、できるだけ速く、距離計算を行いたいと考えています。 具体的には、8bit符号なし整数列の距離計算です。 SSEを利用するのが速いので、 _mm_sad_epu8()を使って組みました。 確かに高速に動作しておりますが、 本当はSAD(絶対誤差の総和)ではなく、SSD(2乗誤差の総和)を求めたいのです。 8bitの符号なし整数列を32bitの符号付き整数列に置き換えてから、 計算するのだとは思いますが、どのように組めば効率が良いのか分かりません。 計算の流れは、 ・8bit→32bit ・32bit整数列の差分 ・32bit整数列の乗算(2乗) ・32bit整数列の総和 となると思いますが、 8bit→32bitを行う関数も見当たらないですし、 符号付き32bit整数列の乗算関数も見当たりません。 どなたかご存知であれば、教えていただけると幸いです。

  • kumav
  • お礼率76% (32/42)

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

 こんにちは。  かじり程度で、mmx/sseを使用した事があるだけなのですが・・・。一応お話だけでも。  乗算の方は色々有りすぎて、分からないのですが、 >>8bit→32bitを行う関数  の方は pinsrw と言う命令が、xmm/mmレジスタの任意の場所に向かってデータを置けるので、其れを利用して並べると言うのなら出来ます。  対応する関数は、  PINSRW __m64 _mm_insert_pi16 (__m64 a, int d, int n)  PINSRW __m128i _mm_insert_epi16 ( __m128i a, int b, int imm)   ですが、ストレートに書いてしまった方が楽だと思います。  アラはあるとは思いますが、其処は勘弁です。本当に早いかどうかは不明です・・・。 // simdblast.cpp : コンソール アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" #include "emmintrin.h" __m128i ui8_to_i32(const unsigned __int8 buf_i8[4]) { __declspec(align(16)) __m128i mem; __asm { //pushad xor ecx, ecx mov esi, buf_i8 mov eax, [esi] mov cl, al pinsrw xmm0, ecx, 0 mov cl, ah pinsrw xmm0, ecx, 2 shr eax, 16 mov cl, al pinsrw xmm0, ecx, 4 mov cl, ah pinsrw xmm0, ecx, 6 movaps mem, xmm0 //movups mem, xmm0 //popad emms } return mem; } int _tmain(int argc, _TCHAR* argv[]) { __declspec(align(16)) __m128i a = {5,6,7,8}; __declspec(align(16)) __m128i b = {1,2,3,4}; ::printf("1バイト\n"); for(int i = 0; i < 4; ++i) { ::printf("[a : %d][b : %d]\n", a.m128i_u8[i], b.m128i_u8[i]); } //8bit→32bitへ変換 a = ::ui8_to_i32(a.m128i_u8); b = ::ui8_to_i32(b.m128i_u8); ::printf("4バイト\n"); for(int i = 0; i < 4; ++i) { ::printf("[a : %d][b : %d]\n", a.m128i_i32[i], b.m128i_i32[i]); } return 0; }

kumav
質問者

お礼

御礼が遅くなって申し訳ありません。 ソースまで紹介していただき非常に助かりました。 何とか組めそうです。 本当にありがとうございました。

関連するQ&A

  • 符号付32bit整数→16bit整数

    以前、Excel関数を使って上位、下位に分かれた符号付16bit整数を32bit符号付整数に変換する式を見つけ使用させていただき大変助かっています 今回はそのまったく逆でExcel関数を使って符号付32bit整数を上位、下位に分かれた符号付16bit整数に分割したいのですが上手くいかずに困っています 解る方いらっしゃいましたら教えてください よろしくおねがいします

  • 加算器を使った乗算器の回路図についての質問です。

    加算器を使った乗算器の回路図についての質問です。 3bitと3bitの乗算で6bitの乗算器の回路図を書いています。 筆算の要領をそのまま、回路図にしてみたのですが、このような形でいいのでしょうか? ネットや手持ちの参考書を見ても乗算器の回路図は載っていなかったため、質問しました。 また、符号がつく乗算器と、符号なしの乗算器では、回路をどのように変化させればいいのでしょうか? よろしくお願いいたします。

  • 浮動小数点とIEEE754

    初めまして。 現在、浮動小数点について調べています。 #質問カテゴリ、間違っていたらすみません。 色々調べていると、こんなサイトを見つけました。 http://www.jtw.zaq.ne.jp/kayakaya/new/kihon/text/fudo.htm 分かり易い解説だったんですが、疑問も湧いてきました。 サイトの内容は、0.375を浮動小数点に直すという内容なんですが 汎用型の時は『0.11 × 2の-1乗』 IEEE754の時は『1.1 × 2の-2乗』 で計算しています。 Q1) 汎用とIEEEの違いは『127』を足すだけだと思っていたのですが 『2の-n乗』の直し方も異なるのでしょうか。 もう一つ質問です。 整数入力をIEEE754に準拠したフォーマットで出力させるデジタル回路を作成しています。 出力形式は32bit or 64bitです。(単精度か倍精度) そこで悩んでいるのが入力のbit数とその内訳です。 入力bitは『符号・整数・小数』で形成されているかと思うのですが 符号以外のbit内訳が分かりません。 Q2) 単精度/倍精度、それぞれの入力範囲bitと、その内訳を教えて頂けないでしょうか。 (単精度:合計16bit ⇒ 符号1bit、整数7bit、小数8bit)みたいな感じでお願いします。 宜しくお願いします。 分かりにくい質問でしたらご指摘下さい。

  • Excel関数 16bit→32bi符号付き整数

    お世話になります。 Excel2010にて、16bit符号付き整数の上位・下位の値が元データとしてあり、 それを32bit符号付き整数に関数を使って変換したいのですが、方法がわからず、質問させて頂きます。 例 セルA1に下位用 -1640 セルA2に上位用 -1 の時に セルA3に32bit符号付き整数表示 わかられます方、ご助力のほどよろしくお願い致します。

  • エントロピー(情報量)について

    エントロピー(情報量)について 画像符号化について質問があります. 符号化では主に予測を行い,予測誤差を算出しています. 元々の画像が 8bit/pel だった場合,誤差の範囲は-255~255となり 9bit/pel となります. ここで質問があります. 予測誤差のエントロピーって単純に出現した誤差の出現頻度を求めて,計算すれば良いのですか? 実際の誤差の範囲(max-min+1)が8bit(0~255)におさまっていなくても良いのでしょうか? お願いいたします.

  • エクセル関数で平方和を求める関数について教えてください.

    列A,Bに割り付けられているデータが各20個あります. (A1-B1)の二乗,(A2-B2)の二乗,・・・の総和を求める関数とその使い方について教えてください.

  • 16進数の文字列

    16進数の文字列をそれと同値な整数値へ変換する関数をかけという問題なのですが、 この場合文字列を読み込んで、例えば読み込んだ値がABだとした場合、 A*16の1乗+B*16の0乗 を計算する関数を作ればよいのだと思うんですが、 それぞれの値をべき乗する関数も必要になってくると考えています。 そこで問題なのですが、べき乗の関数を作ったとして、それぞれの値(こんかいはAとB)にそれぞれのべき乗した値をかけてやるには、どういった方法があるのでしょうか? 回答よろしくお願いします。

  • 浮動小数点表示 加算方法 IEEE

    指数部3bit、仮数部4bit、符号1bitの合計8bitの2進数の浮動小数点表示で、 (1)0.125+0.125+2.5 (2)2.5+0.125+0.125   (10進数) を計算せよ。 という問題です。 0.125(10)は00000000(2)、2.5(10)は01000100(2)となることはわかるのですが、この二つの計算方法がよく理解できません。 どちらかが誤差が生じたりすると思うのですが、それがよくわからず困っています。 教えてください。

  • 文字列と整数型について

    はじめまして。 どうしても困っているのでヒントでも良いのでおねがいします。 関数内(func1)で確保した文字列変数のポインタを 別の関数(func2)にポインタ渡しします。 func2内で整数型で計算した結果を引数で示された文字列変数に 代入するというようなことをしたいと思ってます。 ここで、intは4byteとします。 メモリ長だけで見ると、bit[4] = tmp です。 void func1(){ char bit[4]; func2(bit); return; } void func2(char* p){ int tmp = 0x10101100; p = tmp; <---- ??? return; } そこでどのようにすれば、 代入することができるのか分かりません。 以下のような結果になるように代入したいと思っています。 bit[0] = 0x10; bit[1] = 0x10; bit[2] = 0x11; bit[3] = 0x00; 小さな文字列型に整数型をどのように渡せばよいのかが 一番疑問に思っているところです。 整数型に文字列型を代入する場合には 文字列のバイト指定とシフト演算で実現できています。 ヒントでもよいのでお願いします。

  • [応用情報]BCDの最大値について

    以下の問題を解いています。 ------------------------------------------------------------------------------------------- 第16問 4nビットを用いて整数を表現するとき,符号なし固定小数点表示法で表現できる最大値をaとし,BCD(2進化10進符号)で表現できる最大値をbとする。nが大きくなるとa/bはどれに近づくか。 --------------------------------------------------------------------------------------------- この解説で、BCDで表現できる最大値は、以下とあるのですが、なぜ9なのか?なぜ102なのかがわかりません。符号付だと4の1乗ビット=15ということは理解しています。 どなたか解説いただけませんでしょうか。 4の1乗ビット=9 4の2乗ビット=99≒10の2乗 4の3乗ビット=999≒10の3乗 4の4乗ビット=9999≒10の4乗 4のn乗ビット=10のn乗

専門家に質問してみよう