MMX SSE 3D NOW!のプログラミング

このエントリーをはてなブックマークに追加
932デフォルトの名無しさん:2010/03/18(木) 08:00:20
>>924
え、Complex Decoder Pathを並べるとパイプライン詰まるの?
OoOしてくれるかと思ってた。
シフトはいらないね。
andはどこで使うんだろう。

>>931
うん、897に合わせて書いているけど931がすぐ発想し易いようにしてある。

本質的にはどれ使っても大した違いはないという事が言いたかっただけだから。
933デフォルトの名無しさん:2010/03/18(木) 08:17:34
どうせ大したことない差だし0.25、0.5、0.125でもいいかな、と。
自分で書いてみましたが、SSE使っても最初のと速度変わらないままでした。
934デフォルトの名無しさん:2010/03/18(木) 08:21:24
>>917がどうやったのかが知りたいなあ。
935,,・´∀`・,,)っ-○○○:2010/03/18(木) 09:11:00
>>932
アウトオブオーダなのはデコード後であってデコーダの解釈は並べた順。
936|ω・`):2010/03/18(木) 10:05:49
>>933
いや使い物にならないと思う
rgb 255 入れたとき w 221にしかならないじゃん

じゃ俺も貼るか、ループの中だけでいいよね
937デフォルトの名無しさん:2010/03/18(木) 10:53:15
>>936
> rgb 255 入れたとき w 221にしかならないじゃん
え?それに何か問題でも?
938デフォルトの名無しさん:2010/03/18(木) 14:15:08
白が灰色になっても困らないのか?
939デフォルトの名無しさん:2010/03/18(木) 16:30:30
必要じゃなきゃ困らないだろ
940|ω・`):2010/03/18(木) 21:08:00
おう遅くなった

; asm
; edi=dst+siz*4, esi=src+siz*4, ecx=-siz*4
.lp:
   mov     al, [esi+ecx]
   mov     bl, [esi+ecx+1]
   mov     dl, [esi+ecx+2]
   shr     al, 2
   shr     bl, 1
   add     al, bl
   shr     dl, 3
   add     al, dl
   mov     [edi+ecx], al
   mov     [edi+ecx+1], al
   mov     [edi+ecx+2], al
   add     ecx, 4
   jnz     .lp
941|ω・`):2010/03/18(木) 21:10:00
.lp: ; mmx2 edx=dst+siz*4, eax=src+siz*4, ecx=-siz*4, mm0=zero, mm7=factor
   movq      mm1, [eax+ecx]
   movq      mm2, mm1
   punpcklbw mm1, mm0
   punpckhbw mm2, mm0
%ifdef accurate
   pmaddwd   mm1, mm7
   pmaddwd   mm2, mm7
   pshufw    mm4, mm1, 0b11111110
   pshufw    mm5, mm2, 0b11111110
   paddw     mm1, mm4
   paddw     mm2, mm5
   pshufw    mm1, mm1, 0b11000000
   pshufw    mm2, mm2, 0b11000000
   psrlw     mm1, 8
   psrlw     mm2, 8
%else
   pmulhuw   mm1, mm7
   pmulhuw   mm2, mm7
   pshufw    mm4, mm1, 0b11001001
   pshufw    mm5, mm2, 0b11001001
   paddw     mm4, mm1
   paddw     mm5, mm2
   pshufw    mm1, mm1, 0b11010010
   pshufw    mm2, mm2, 0b11010010
   paddw     mm1, mm4
   paddw     mm2, mm5
%endif
   packuswb  mm1, mm2
   movntq    [edx+ecx], mm1
   add       ecx, 8
   jnz       .lp
942|ω・`):2010/03/18(木) 21:11:00
; ssse3
; edx=dst+siz*4, eax=src+siz*4, ecx=-siz*4, xmm0=zero, xmm6=shuffle, xmm7=factor
.lp:
   movdqa    xmm1, [eax+ecx]
   movdqa    xmm2, xmm1
   punpcklbw xmm1, xmm0
   punpckhbw xmm2, xmm0
%ifdef accurate
   pmaddwd   xmm1, xmm7
   pmaddwd   xmm2, xmm7
   phaddd    xmm1, xmm2
%else
   pmulhuw   xmm1, xmm7
   pmulhuw   xmm2, xmm7
   phaddw    xmm1, xmm2
   phaddw    xmm1, xmm2
%endif
   pshufb    xmm1, xmm6
   movntdq   [edx+ecx], xmm1
   add     ecx, 16
   jnz     .lp
943|ω・`):2010/03/18(木) 21:12:00
; ssse3 pmaddubsw
; edx=dst+siz*4, eax=src+siz*4, ecx=-siz*4, xmm5=mask, xmm6=shuffle, xmm7=factor
.lp:
   movdqa    xmm1, [ecx+eax]
%ifdef accurate
   movdqa    xmm2, xmm1
   pand      xmm2, xmm5
%else
   pand      xmm1, xmm5
%endif
   pmaddubsw xmm1, xmm7
%ifdef accurate
   paddw     xmm1, xmm1
   paddw     xmm1, xmm2
%else
   psrlw     xmm1, 3
%endif
   phaddw    xmm1, xmm1
   pshufb    xmm1, xmm6
   movntdq   [ecx+edx], xmm1
   add     ecx, byte 16
   jnz     .lp
944|ω・`):2010/03/18(木) 21:13:00
;segment .data

%ifdef accurate
qFactorW:
dqFactorW:
   dw 77,150,29,0,77,150,29,0
dqShufB:
   db 1,1,1,255,3,3,3,255,5,5,5,255,7,7,7,255
dqShufB159d:
   db 1,1,1,255,5,5,5,255,9,9,9,255,13,13,13,255
dqFactorB:
   db 38,75,14,0,38,75,14,0,38,75,14,0,38,75,14,0
dqMaskB:
   db 0ffh,0,0ffh,0,0ffh,0,0ffh,0,0ffh,0,0ffh,0,0ffh,0,0ffh,0,
%else
qFactorW:
dqFactorW:
   dw 16384,32768,8192,0,16384,32768,8192,0
dqShufB:
   db 0,0,0,255,2,2,2,255,4,4,4,255,6,6,6,255
dqFactorB:
   db 2,4,1,0,2,4,1,0,2,4,1,0,2,4,1,0
dqMaskB:
   db 0fch,0feh,0f8h,0,0fch,0feh,0f8h,0,0fch,0feh,0f8h,0,0fch,0feh,0f8h,0
%endif
945デフォルトの名無しさん:2010/03/18(木) 21:48:44
>>940
ssse3(>>942)の!accurateを試してみたけど>>917みたいな大きな差が現れないどころか、純粋なCのプログラムより若干遅いんだけど。
946|ω・`):2010/03/18(木) 21:57:34
それはさすがにないはず
なんか間違ってるんじゃない

あと実は917のときより全部ちょっと速くなってる
siz=1024 65536 4194304
// 45nm shift
4.08 4.44 7.50 gcc4
4.02 4.38 7.43 asm
3.98 3.87 5.08 mmx2
2.37 2.26 4.80 ssse3
2.36 2.27 4.78 ssse3_2 (pmaddubsw)

// 65nm shift
4.02 4.44 5.77 asm
4.39 3.89 4.55 mmx2
3.94 3.29 4.46 ssse3
2.66 2.19 4.44 ssse3_2 (pmaddubsw)

// 45nm accurate
4.73 4.90 7.35 asm
3.94 3.84 5.08 mmx2
2.36 2.26 4.80 ssse3
2.36 2.26 4.81 ssse3_2 (pmaddubsw)

// 65nm accurate
4.82 4.93 6.08 asm
4.36 3.78 4.57 mmx2
2.82 2.34 4.49 ssse3
2.77 2.26 4.43 ssse3_2 (pmaddubsw)

gcc4 は -mtuneを pentium-m 以前にしたら途端にまともなコードを吐くようになった
947|ω・`):2010/03/19(金) 00:28:20
あ、! 見逃してた。accurate じゃない方ってこと?
なら 65nm で L1 の中なら肉薄されるね
L1 内でループ回したら負けるかも

そういうセットアップだと、まず movnt を普通の mov にして
それから phadd とか pshufb とかバラすといいのかな? 団子が詳しそうだけど
948,,・´∀`・,,)っ-○○○:2010/03/19(金) 01:16:42
phaddはpermute×2 + paddに分解されるので遅いです><

ビットマスクしてpsadbw(乗算扱い)した方が速いよ。精度はさておき。
949,,・´∀`・,,)っ-○○○:2010/03/19(金) 01:32:58
実はSSSE3を使えばpmaddubsw→pmaddwd→pshufbだけでできるんだな。

pmaddubswの第2引数
__m128i vGSMultipler1 = _mm_set_epi8(
ScaleR, ScaleG, ScaleB, 0,
ScaleR, ScaleG, ScaleB, 0,
ScaleR, ScaleG, ScaleB, 0,
ScaleR, ScaleG, ScaleB, 0
);

pmaddwdの第2引数
__m128i vGSMultipler2 = _mm_set_epi16(1, 1, 1, 1, 1, 1, 1, 1);

pshufbの第2引数
__m128i vSplat = _mm_set_epi8(
0xff, 15, 15, 15,
0xff, 11, 11, 11,
0xff, 7, 7, 7,
0xff, 3, 3, 3);
950,,・´∀`・,,)っ-○○○:2010/03/19(金) 01:43:22
いずれにしても乗算ネックなんで悩ましい。
どうせ乗算ネックなら精度的にはR, BとG, 0に分けてpmaddwdの方が良いと思う。
951デフォルトの名無しさん:2010/03/19(金) 14:41:13
0BGR -> GBGRで
ScaleGを分割して精度を1bit稼ぐのはどうだ
952|ω・`):2010/03/19(金) 18:09:31
片方無駄なphaddより全1掛ける方がどう考えてもいいね
ていうか手元の最新コードではそうなってた
でもさすがにバイトの和は使えないと思う

> 精度を1bit稼ぐ
お、気づいてくれた?
953951:2010/03/20(土) 04:52:11
ScaleGが4bitだから、1bit増えても5bitにしかならないから
ScaleGの精度だけ上げて
pmaddwd時に小数点の位置を合わせたほうがいのか
954デフォルトの名無しさん:2010/03/20(土) 05:54:02
SSEを使って最適化を進めて、「やった2倍だ3倍だ」と思っていたら、
複数のコアを使ったら殆ど変わらなくなった時って悲しくならねぇ?
955,,・´∀`・,,)っ-○○○:2010/03/20(土) 07:10:28
メモリ帯域とりあうからな
ただ、メモリ帯域取らない別のワーカースレッドを並列稼働させればいいし
4コア分の仕事を1コアで賄えるなら結果省エネになる。
956デフォルトの名無しさん:2010/03/20(土) 10:12:00
>>954
マルチスレッドにしなきゃいかんし、4コアで別々にSSE使えるからもっと速くなるから
無駄ではないだろ
957,,・´∀`・,,)っ-○○○:2010/03/20(土) 10:21:39
外部メモリ帯域がネックじゃなければね
共有キャッシュ上のデータをうまく使い回してDRAM帯域をセーブするテクニックが必要になるし
なおかつそういう用途でしか使い物にならない。
958951:2010/03/20(土) 14:11:27
>>953
ScaleGじゃなくてScaleBだった
959デフォルトの名無しさん:2010/03/20(土) 16:22:28
SIMD化そのものが無駄。
正確にはSIMDに合わせて、SISDのコードをSIMDに加工するのが無駄。
たまたま無理なくSIMDに出来るコードがあったらやる程度で十分。
960デフォルトの名無しさん:2010/03/20(土) 16:51:41
SIMDを極めた人が言うなら説得力がある。
そう出なければ単なる負け惜しみ。
けど、SIMDを極めた人は最初からSIMDを意識して設計するんでない?
961デフォルトの名無しさん:2010/03/20(土) 17:05:26
単純なコードだとコンパイラの最適化のほうが速いってこともあるよ
962,,・´∀`・,,)っ-○○○:2010/03/20(土) 17:14:54
画像処理みたいなデータ並列度の高い処理で使わないのはただの無能
963デフォルトの名無しさん:2010/03/20(土) 19:02:59
ところでなんで団子や>>831>>834みたいに
_mm_xxx_yyyの形で書く人がいないんだろ
知り合いとかもみんな基本はC使ってるくせにアセンブラ使いたがるよね
まあ単に俺がアセンブラ嫌いなだけなんだけど
964デフォルトの名無しさん:2010/03/20(土) 19:37:18
コンパイラが信用出来ない by x264の中の人
965|ω・`):2010/03/20(土) 20:11:28
くれてない、かな

pmaddubsw は片方符号付で7bit精度しかないんだけど
943ではちょっと工夫して他と結果そろえてる
実は速度とかよりここがメインだったんだけどなぁ

こだわらないなら団子の言う3命令だけでもできると思うけど
ただ>>949は引数全部違うよね
966,,・´∀`・,,)っ-○○○:2010/03/20(土) 22:27:22
>>964
たまにアセンブラすら信用できないこともあるけどな、特にNで始まるあれは。
致命的なバグ大杉。

>>965
ごめん書いてから気づいたけど誰も突っ込まないから放置してた。


本当はYASM使いだけど、Cコードはかなりテキトーに書いた。引数順序とかテキトー
x86->x64, SSE->AVXの移行考えるならIntrinsics形式の方が楽だと思う。

967デフォルトの名無しさん:2010/03/21(日) 02:11:47
>>963
Cコンパイラがメモリ参照するコードばかり吐き出しよるとです。
968デフォルトの名無しさん:2010/03/21(日) 02:47:18
VCで/arch:SSE2やるとmovdqaとかにアラインされてないアドレス渡すコード吐くことがあったな
969デフォルトの名無しさん:2010/03/21(日) 03:19:14
>>952
>>943で精度を1bit稼いでるのは気づいていなかった
>>943
((77*R + 150*G) + 29*B)

((38*R + 75*G) + 14*B)*2 +R +B
に変形しているけど

>>951で書いたのはこの変形
(77*R+51*G) + (29*B+99*G)
970|ω・`):2010/03/21(日) 04:49:38
>>969
なるほどねえ、そっちは俺が気づいてなかった
幅いっぱい使いきってるのが美しい

45nm 以降なら shufb 一発で済んで3命令得だし
65nm だと uop 数変わんないけど遅くはならないはず
そっちの方が断然いい
971デフォルトの名無しさん:2010/03/21(日) 23:31:09
2005はもう捨てろ
972デフォルトの名無しさん:2010/03/22(月) 20:27:46
6年かかったけどそろそろ次スレに行けそうだな
もう3D Now!は要らないんじゃない?
973デフォルトの名無しさん:2010/03/22(月) 23:15:53
つまりそれだけ需要がなかったか、あるいは、この技術を必要とするプログラマが少なかったということか。
まあ、全体としてはマイノリティだけどな。
974デフォルトの名無しさん:2010/03/23(火) 00:51:27
>>957
メモリ帯域に対してSSEの処理が速すぎるんだよね。
しかもハードウェアプリフェッチが機能するようになってから、
余計メモリ帯域を消費するようになった。

メモリ転送レイテンシ以下で32bitや64bit変数を圧縮、展開を出来るアルゴリズムはないのかな?
多少圧縮展開で時間がかかっても並列化によって計算時間は相対的に下がるから、
メモリ帯域をセーブ出来ると思うんだけどな。
そんなにあまくないか。
975デフォルトの名無しさん:2010/03/23(火) 01:21:37
むしろそのうちメモリバスにスクランブルかかるんじゃないの?

レイテンシー増えるけど著作権のためよ♪by利権団体
976デフォルトの名無しさん:2010/03/23(火) 02:32:21
なんかどこぞ団体はいいそうだね。
メモリ毎に保証料払えと。
ただPCIExpressとかは輻射の低減ため、
スクランブルが掛かっているけどね。
977デフォルトの名無しさん:2010/03/23(火) 12:44:47
製品単位で取ってるから、多重請求になっちまう。
978,,・´∀`・,,)っ-○○○:2010/03/31(水) 16:07:12
>>972
次の6年に備えて「SSE AVX XOP」でおk
979デフォルトの名無しさん:2010/04/01(木) 21:52:12
初心者質問で悪いんだが
1.パイプラインの使用率を見る方法
2.どの程度まで使用率を上げられるものか

教えてくだされ
980デフォルトの名無しさん:2010/05/24(月) 14:01:42
 V V
(´・ω・`) うさちゃんピース
981デフォルトの名無しさん
>>975
マザボの大半は著作権フリーの台湾で作っているのでまずあり得ない