[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 2chのread.cgiへ]
Update time : 10/27 07:58 / Filesize : 141 KB / Number-of Response : 567
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

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



1 名前:デフォルトの名無しさん [04/05/28 22:00]
どうぞ

45 名前:デフォルトの名無しさん mailto:sage [2005/07/27(水) 16:10:13 ]
Intelのページに、SSE3を使わないコードと使うコードの例が載ってた。

mulps xmm0, xmm1
movaps xmm1, xmm0
shufps xmm0, xmm1, 0xb1
addps xmm0, xmm1
movaps xmm1, xmm0
shufps xmm0, xmm0, 0x0a
addps xmm0, xmm1

これは1個ずつやっているな。


mulps xmm0, xmm1
haddps xmm0, xmm0
haddps xmm0, xmm0

SSE3はすごいなあ。同じhaddpsを続けただけでできてしまう。
ていうか3D Now!もそうか。K6-2が、はまればすごく速かったのがわかる気がした。

ただ、Prescottではhaddpsのタイミングが13-4なんだよな。
上のコードに7+13+13 = 33clkもかかる。
Athlon64だとhaddpsが5-2、mulpsが5-2。5+5+5 = 15clkかな。

ただ、Pen4ならこの33clkのブロック自体を何個も並列に実行しそう。


2個同時でも
haddps xmm0, xmm1
haddps xmm0, xmm0
これでOK。何者だよっていう簡単さだな。
内積を、どう利用するかによって、移動命令で欲しい形式に落とすのも腕の見せ所。

46 名前:デフォルトの名無しさん mailto:sage [2005/07/28(木) 18:54:46 ]
>>45
やっぱ要素間演算がないのは皆不満だったらしいね。
便利だけど自分の環境じゃ試せないのが痛いなぁ。

にしてもSSE3は便利なのはいいけどホント遅そうだ。

47 名前:デフォルトの名無しさん mailto:sage [2005/07/29(金) 10:06:21 ]
そんなに遅くはないんじゃない?
Prescottはもう死にかけのアーキだし、K8なら速いし。
YonahのSSE3も速くなってると思う。

48 名前:デフォルトの名無しさん mailto:sage [2005/07/31(日) 10:18:47 ]
そうかぁ。やっぱSSE3使ってみたいなぁ。
この夏に新しい石のAthlonでも買って試してみるか。

まあPrescottでも流れれば速いのかな?

49 名前:デフォルトの名無しさん mailto:sage [2005/08/01(月) 10:26:31 ]
>>48
うん、流れたときの速さは比べるものがないほどだと思う。
リアル128bitでバラバラに動くSIMDは強力。
レジスタ間movapsのレイテンシが6なことなど気にならない。

50 名前:デフォルトの名無しさん mailto:sage [2005/08/14(日) 19:40:00 ]
最悪だ・・・ノートのバッテリーが逝ってしまわれた・・・金が・・・
SanDiegoもVeniceもさようなら〜orz

51 名前:デフォルトの名無しさん [2005/08/25(木) 14:50:35 ]
sse3の使えない環境でsse3を使ったプログラムを走られたらどうなりますか?

52 名前:デフォルトの名無しさん mailto:sage [2005/08/25(木) 15:05:09 ]
Illegal Instruction例外で落ちます。

53 名前:デフォルトの名無しさん mailto:sage [2005/08/27(土) 19:01:02 ]
>>51
bochsという強力なエミュなら、どんな環境でもSSE,SSE2,SSE3,x64,3dnowなど
なんでもエミュレートできるぞ。
どんな環境でもって言うのはPowerPCでもSPARCでもってこと。



54 名前:デフォルトの名無しさん mailto:sage [2005/10/01(土) 21:24:26 ]
人いない・・・

55 名前:デフォルトの名無しさん mailto:sage [2005/10/03(月) 14:38:06 ]
ほんとにいませんねえ。
今までにSIMDで何を作ったことがあるか書いていくか?

56 名前:デフォルトの名無しさん mailto:sage [2005/10/03(月) 16:24:49 ]
行列の掛け算・・・・

57 名前:デフォルトの名無しさん mailto:sage [2005/10/03(月) 18:12:16 ]
いまから拡張命令使ってFirefoxを最適化してみようと思う。

58 名前:名無し募集中。。。 mailto:sage [2005/10/03(月) 18:45:09 ]
[word data1][word data2][word data3]・・・
[word data100][word data101][word data102]・・・
こんなふうに並列演算したいデータがメモリ上に並んでいない場合
data1とdata3とdata100とdata102を並列計算したい時って
pinsrw でデータを集める以外にうまいやり方ってない?
movq でメモリから64bit取り出してパックしたほうが早いかな?

59 名前:デフォルトの名無しさん mailto:sage [2005/10/03(月) 19:58:56 ]
まずはデータ構造を見直せ。
すべてはそこからだ。

60 名前:名無し募集中。。。 mailto:sage [2005/10/03(月) 20:13:33 ]
データ構造はCCDのRAWデータだから仕方ないよ
[R][G][R][G]
[G][B][G][B] という配列(今回扱うのは1画素12bit)

61 名前:デフォルトの名無しさん mailto:sage [2005/10/04(火) 10:54:24 ]
SSEの整数命令って単にMMX命令のオペランドに
MMXレジスタだけじゃなくてSSEレジスタも使えるようになったってだけ?
しかも64ビットまでしか使えないって罠で利点はemmsなしでOKってだけ?

ここからチラシの裏
FirefoxのビルドしたらAthlonノートでやけどしたw
しかし最適化といってもどこから手を付けていいのやら。
テテさんとかどうやってんだろうね。

62 名前:デフォルトの名無しさん mailto:sage [2005/10/05(水) 09:08:10 ]
>>61
SSE整数は128bit使ってるよ。
ただ、現状ではMMXが速いことが多いけど。

将来的には演算器が強化されてSSEの方が速くなるだろうし、
x64ではレジスタが倍の16本に増えるというメリットもある。

63 名前:デフォルトの名無しさん mailto:sage [2005/10/05(水) 19:29:28 ]
SSE2じゃそうだろうけど初代SSEでもできんの?



64 名前:デフォルトの名無しさん mailto:sage [2005/10/06(木) 08:58:39 ]
>>63
初代SSEとは、MMX2のことかい?

65 名前:デフォルトの名無しさん mailto:sage [2005/10/15(土) 08:03:38 ]
はやくSSEのスループットが1にならないかなー。

66 名前:デフォルトの名無しさん mailto:sage [2005/10/15(土) 14:31:23 ]
SSEの演算器だけ倍速作動とかw

67 名前:デフォルトの名無しさん mailto:sage [2005/10/16(日) 15:41:44 ]
ある程度トランジスタ割けば、SSEユニットを倍積めるんだろうか。
単純に演算器の数を倍にするの。

68 名前:デフォルトの名無しさん mailto:sage [2005/10/22(土) 10:59:10 ]
>>61
チラシの裏
MMXのmovqを使ってメモリコピーを高速化してるよ。
SSE系は使ってないみたい。

69 名前:デフォルトの名無しさん mailto:sage [2005/10/22(土) 14:11:26 ]
現状じゃ128bitのロード・ストアは遅いもんな。

Pen4だけは128bitの方が速いけど、
これも幅が広いから小回り効かなくて遅いのかな。

70 名前:デフォルトの名無しさん mailto:sage [2005/11/21(月) 01:03:24 ]
packed byteな乗算命令がなくて(´・ω・`)ショボーン

71 名前:デフォルトの名無しさん mailto:sage [2005/11/21(月) 10:15:15 ]
俺は多倍長データ加算用のSIMD命令がほしい。

72 名前:デフォルトの名無しさん mailto:sage [2005/11/23(水) 08:58:42 ]
勝手に3D NOW!!に対応してくれるコンパイラ無いかな。


73 名前:デフォルトの名無しさん mailto:sage [2005/11/23(水) 10:03:48 ]
>>72
対応って自動ベクトルか機能のことをいってるのか?
そうならこいつがあるが
ttp://www.codeplay.com/japanese/vectorc/feat-vec.html





74 名前:デフォルトの名無しさん mailto:sage [2005/12/11(日) 10:48:57 ]
CQ出版が15日に出す本が良本ならこのスレも
盛り上がってくれることを信じつつwktk


75 名前:デフォルトの名無しさん mailto:sage [2005/12/12(月) 01:08:17 ]
微妙な本だな。大体一章が10ページくらいのB5判だから、
基本的な触りくらいしか出てないようなヨカソ
インテルのマニュアルの方がよっぽど詳しいのではなかろうか。

76 名前:デフォルトの名無しさん mailto:sage [2005/12/12(月) 22:36:34 ]
>>75
そら純正マニュアルに敵う本なんてまずないだろ……

77 名前:デフォルトの名無しさん mailto:sage [2005/12/15(木) 10:37:25 ]
早速買って来たよ。
SSE2の日本語+絵による解説は使えそう。


78 名前:デフォルトの名無しさん mailto:sage [2005/12/16(金) 04:01:41 ]
>>77
nyで

79 名前:デフォルトの名無しさん mailto:sage [2006/01/02(月) 01:04:22 ]
altivecはここじゃだめですか

80 名前:デフォルトの名無しさん mailto:sage [2006/01/05(木) 19:01:14 ]
SIMD命令を使ったトリッキーなコード、意外な使い方ってないですか。
簡単なやつでもいいので。

homepage1.nifty.com/herumi/adv/bbslog/bbs11.html
の498,519みたいな。

81 名前:デフォルトの名無しさん mailto:sage [2006/01/15(日) 17:20:05 ]
iccでemmintrinつかってるんですが、
__m128 <-> __m128dのキャストをインラインアセンブリ
使わずにできます?
倍精度の仮数部の一部を整数演算で0クリアしたいんです。


82 名前:デフォルトの名無しさん mailto:sage [2006/01/15(日) 17:45:45 ]
_m128iを引数とする関数で_m128dをそのままの形で使いたいって事でOK?

__m128d a;
__m128i b;
b = _mm_and_si128(*(__m128i*)&a,b);

83 名前:デフォルトの名無しさん mailto:sage [2006/01/15(日) 17:53:53 ]
>>82
メモリアクセスするコードが生成されないか心配。



84 名前:デフォルトの名無しさん mailto:sage [2006/01/15(日) 18:27:53 ]
んじゃこっち

union {
  __m128d a_d;
  __m128i a_i;
}
__m128i b;
(ry

85 名前:デフォルトの名無しさん mailto:sage [2006/01/15(日) 22:13:20 ]
助言あんがと。
s=_mm_cvtpd_ps(d);
d=_mm_cvtps_pd(s);
てなことを
d=_mm_and_si128(d,mask);
てな感じで済ませたかったけど、
union使って書くと遅くなったんで最適化してくれないっぽ…
入力がfloatの範囲を越えても動かしたいんだけどなぁ


86 名前:デフォルトの名無しさん mailto:sage [2006/01/15(日) 22:18:25 ]
インラインでガリガリ書くしかなくね?

87 名前:デフォルトの名無しさん mailto:sage [2006/01/15(日) 23:44:17 ]
なるべくアセンブリは避けたかったですが、
inline __m128d round(__m128d d,__m128i mask){
__asm__ __volatile__ ("pand %1,%0" : "+x"(d) : "x"(mask));
return d;
}
で少し速くなりました。
どもども。


88 名前:デフォルトの名無しさん mailto:sage [2006/02/06(月) 14:49:39 ]
720*480のBMPを640*480に縮小するのにMMXを使えないか思案中。

89 名前:デフォルトの名無しさん mailto:sage [2006/02/06(月) 16:32:46 ]
640*480側で8ピクセル(24byte=MMX*3)ずつやればいいかな。
720*480側は普通に読むのと3byteずらして読むのをやって
掛け算で加重して・・・あ、MMXの乗算は16bitだけか。
どのくらいの速度になるだろ。

90 名前:デフォルトの名無しさん mailto:sage [2006/02/06(月) 18:01:30 ]
久しぶりだったから配列のアドレスをmovでeaxに入れようと四苦八苦してしまったorz
今からbmpの構造を思い出そうとしている俺は完全に出遅れかな?

91 名前:デフォルトの名無しさん mailto:sage [2006/02/06(月) 18:42:06 ]
>>90
つoffset

92 名前:デフォルトの名無しさん mailto:sage [2006/02/06(月) 21:28:47 ]
>>90
つlea

93 名前:デフォルトの名無しさん mailto:sage [2006/02/06(月) 22:07:42 ]
>88
バイリニアをMMXで実装するだけ。
しかも480で縦ライン固定なら1時間くらいで出来るんじゃね?



94 名前:デフォルトの名無しさん mailto:sage [2006/02/07(火) 10:21:03 ]
//横のドット数が9と4の倍数の24bitBMPに対し、横を8/9に縮める
void resize(unsigned char *p,int w,int h)
{
 int i,j,k,n;
 n=w/9*h;
 for (k=0; k<n; k++){
  for (j=0; j<8; j++){
   for (i=0; i<3; i++){
    p[(k*8+j)*3+i]=((8-j)*p[(k*9+j)*3+i]+(1+j)*p[(k*9+j+1)*3+i]+4)/9;
   }
  }
 }
}
9ピクセル*n回の処理。まずCで書いて動作することを確かめた(もはや十分な速度だな・・・)。
MMXもこれと同じ方針で行く。

MMXには除算命令がないので乗算で代用。
精度も16bitだから、8bitの数値に対してはほとんど問題ない。

MMX版のコードは、次のように設定して次レスのコードをn回ループさせる。
short m[48]={8,8,8,7,7,7,6,6,6,5,5,5,4,4,4,3,3,3,2,2,2,1,1,1,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,8,8,8};
n=w/9*h;
eax=m、esi=edi=p
mm5={4,4,4,4} ;=9/2
mm6={7282,7282,7282,7282} ;=10000h/9
mm7={0,0,0,0}

速度は、素通し(HDDのBMPをコピーするだけ)が156ms、MMXが175ms、C版が241ms。
720*480のBMPを5個変換するのにかかった時間(PentiumM)。
まあ、ディスクキャッシュにヒットしなかったら、ずっと遅くなるけど。
本来なら非SIMDアセンブラとの比較もしたいところだが、ここまで。
3個の出力を調べて、MMX版とC版の出力は全て一致していた。

95 名前:デフォルトの名無しさん mailto:sage [2006/02/07(火) 10:21:34 ]
xor ecx,ecx
lp0:
movq mm0,[esi+ecx]
movq mm1,mm0
punpcklbw mm0,mm7
punpckhbw mm1,mm7
pmullw mm0,[eax+ecx*2]
pmullw mm1,[eax+ecx*2+8]

movq mm2,[esi+ecx+3]
movq mm3,mm2
punpcklbw mm2,mm7
punpckhbw mm3,mm7
pmullw mm2,[eax+ecx*2+48]
pmullw mm3,[eax+ecx*2+48+8]

paddw mm0,mm2
paddw mm1,mm3
paddw mm0,mm5
paddw mm1,mm5
pmulhw mm0,mm6
pmulhw mm1,mm6
packuswb mm0,mm1
movq [edi+ecx],mm0
add ecx,8
cmp ecx,24
jnz lp0

add esi,27
add edi,24
;MMXでバイリニアてのはどうやるの?

96 名前:デフォルトの名無しさん mailto:sage [2006/02/09(木) 09:45:01 ]
>>90
変数の中身へのポインタを取得するとアセンブリでは
lea eax,[esp-12]
のようになるから、movは使えないのだね。

int *a;ならmov eax,aできても、int a[4];だとmov eax,aで氏んだからな。
あのときはけっこう悩んだ。

97 名前:デフォルトの名無しさん mailto:sage [2006/02/11(土) 09:08:17 ]
SIMDで計算したいブロックを高級言語で明示できないかな。
たとえば、C言語風の妄想言語...
struct complex_t {
    float r, i;
};
foo() {
    complex c[4];
    VEC( float re : [ c[0].r, c[1].r, c[2].r, c[3].r ], float im : [ c[0].i, c[1].i, c[2].i, c[3].i ] ) {
        float t = re * re - im * im;
        im = 2 * re * im;
        re = t;
    }
とか書くと、VECブロックの中が自動的にSIMD命令で構成される。
( SIMD未対応のCPU向けのときは、通常の命令になる )
SIMDで実行するのだから、VECブロック中には分岐はかけず、
ループも固定回数ループだけ。

どう?この妄想言語。

98 名前:デフォルトの名無しさん mailto:sage [2006/02/11(土) 11:51:13 ]
1つの構造体がメモリ上でバラバラになってるな。
それはいいとして、組み込み関数と演算子オーバーロードでよくない?

ただ、俺もそういう言語は欲しいと思っていた。
せっかくCPUに色々な命令があるんだから、命令が見える言語がいいよね。
そういう意味じゃCのシフト演算子とかナイスと思った。

99 名前:デフォルトの名無しさん mailto:sage [2006/02/11(土) 19:29:54 ]
Intrinsics使えばインジャネ?

最終段で機械任せの最適化するなら、
そのままCでも構わないと思うけど。

100 名前:デフォルトの名無しさん mailto:sage [2006/02/17(金) 21:01:05 ]
8bitビットマップ(グレースケール)から32bitビットマップへの変換を、MMX使って
実装しようとしているのですが、思っていたよりも早くならずに難渋しています。
 適当なやり方しているのは自覚しているのですが、同じく適当にCで書いたルーチン
と、リリース版の最適化コミで速度変わらずってのはかなり凹みました。
 どこかもっと最適化する場所があるのでしょうか? ご存じの方ご教授願います。

void testcopy( void *dst, const void *src, int size )
{
  int size2 = size >> 1;
  if(size2 != 0){
    __asm{
      mov edi, dst;
      mov esi, src;
      mov ecx, size2;
    loop_mp:
      movq mm0, [esi];
      punpcklbw mm0, mm0;
      punpcklbw mm0, mm0;
      movq [edi], mm0;
      lea esi, [esi + 2];
      lea edi, [edi + 8];
      dec ecx;
      jnz loop_mp;
      emms;
    }
  }
}


101 名前:デフォルトの名無しさん mailto:sage [2006/02/17(金) 21:20:54 ]
>>100
使用CPUは何?

lea esi, [esi + 2] はadd esi,2 のが無難だと思う。Pen4ならaddのが速い。
movqは8byteだから最後の2byte読むときに6byte余計に読んでしまうのが気持ち悪い。
速度の面からも、読み取りを2byte毎じゃなく4byteか8byteにするべき。
MMX2が使えるならpshufwを使ってもいいかな。

movd mm0, [esi];
punpcklbw mm0, mm0;
movq mm1,mm0
punpcklbw mm0, mm0;
punpckhbw mm1, mm1;
movq [edi], mm0;
movq [edi], mm1;
add esi,4;
add edi,16;
sub ecx,2;
jnz loop_mp;

即興で作って試してないけど、こんなのでどうでしょ。

102 名前:100 mailto:sage [2006/02/17(金) 21:25:43 ]
>101
>使用CPUは何?
 書き忘れていました。CPUはPen4ですが、諸事情(VC6sp6開発)のため
MMXまでの制限になってます。


103 名前:デフォルトの名無しさん mailto:sage [2006/02/17(金) 21:39:40 ]
そういえば、これ処理が軽いからメモリ速度がボトルネックになるね。
おそらくCで書いたルーチンでもメモリ帯域を使い切っているに近いと思う。

ありえん話だが、メモリがL1キャッシュくらい速い環境ならば
>>100氏はCコンパイラに大勝していただろう。

あと、このように毎回実行する余計な処理が4命令もあるので、
ループをアンロールすれば少し速くなると思う。
lea esi, [esi + 2];
lea edi, [edi + 8];
dec ecx;
jnz loop_mp;

>>102
SP6か。それは残念。後でnasmでも使ってみてください。
Pen4だとALUが速くてMMXが遅いからな。



104 名前:デフォルトの名無しさん mailto:sage [2006/02/17(金) 22:15:40 ]
画像処理はメモリのアクセス速度がボトルネックだよな〜

105 名前:デフォルトの名無しさん mailto:sage [2006/02/17(金) 22:30:45 ]
Microsoft Visual C++ Toolkit 2003
ttp://msdn.microsoft.com/visualc/vctoolkit2003/

106 名前:デフォルトの名無しさん mailto:sage [2006/02/17(金) 23:09:57 ]
SSEが使えればprefetchがあるんだけどなぁ。

107 名前:100 mailto:sage [2006/02/18(土) 10:01:35 ]
 いろいろと助言ありがとうございます。参考にしていろいろ試してみます。

>>103
>後でnasmでも使ってみてください。
 個人で試す分には思いっきりやってみたいところなのですが、
そこまですると引き継ぎが出来なくなって(略)な事になるので……


108 名前:デフォルトの名無しさん [2006/02/18(土) 18:14:08 ]
いまどきアーキテクチャー依存のアクセラレータなど流行らん

109 名前:デフォルトの名無しさん [2006/02/18(土) 20:32:13 ]
>>97
ivec.h
fvec.h
dvec.h
をインクルード


110 名前:デフォルトの名無しさん mailto:sage [2006/02/18(土) 23:38:01 ]
>>109
そういったクラスライブラリじゃなくて言語の拡張仕様に
埋め込んで欲しいって言ってんじゃないの?

111 名前:デフォルトの名無しさん mailto:sage [2006/02/19(日) 00:03:31 ]
>>110
そんなことは言ってない

112 名前:デフォルトの名無しさん mailto:sage [2006/02/19(日) 00:40:17 ]
俺も妄想言語は考えてるよ。つーかみんな一度は考えてるんじゃないかなぁ

multivalue< float, 3 > m0( 1.0f, 2.0f, 3.0f), m1( 5.0f, 5.0f, 4.0f), m2;

simd foreach( float v0 in m0, float v1 in m1, float r0 in m2)
{
float t = v0 * v0 + v1 * v1; 
if( t > 0.9f)
r0 = t;
else
r0 = 0.0f;
}

分岐は、通るブロックは全て実行して最後論理積って形になるかなぁ。
誰か作って、C++へのコンバータでいいからさ。

113 名前:・∀・)っ-○●◎- ◆Pu/ODYSSEY mailto:sage [2006/02/19(日) 02:01:05 ]
どうみてもivec.h/fvec.h/dvec.hの使い方慣れたほうが楽です

F32vec4 m0(1.0f, 2.0f, 3.0f, 0.0f);
F32vec4 m1(5.0f, 4.0f, 4.0f, 0.0f);
F32vec4 m2 = m0 * m0 + m1 * m1;
m2 = select_gt(m2, F32vec4(0.9f, 0.9f, 0.9f, 0.9f), m2, F32vec4(0.0f, 0.0f, 0.0f, 0.0f));



114 名前:・∀・)っ[http://www.coins-project.org/] ◆Pu/ODYSSEY mailto:sage [2006/02/19(日) 02:15:47 ]
ここが実現してくれるの待ちましょう。どうも税金の無駄遣い臭いのだが。

115 名前:デフォルトの名無しさん mailto:sage [2006/02/19(日) 02:28:09 ]
そういや
・データ読み込み
・同アドレスにデータ書き込み
を行った場合、このデータ書き込みの際にmovntiとか使っても全然
早くならないんだけれども、これって対象アドレスに既にデータが入っている
場合、非テンポラル指定はキャッシュ汚染を防ぐためにやるんだから
キャッシュに入っていては意味が無いって事だよな?

116 名前:デフォルトの名無しさん mailto:sage [2006/02/20(月) 13:33:53 ]
>100
vcpp5解凍してml.*をコピーすればSSE2命令くらいまで使えたはず、
ってか俺はVC6SP6で使えてる。
もしくは、VC6インスコ→SP5→vcpp5→SP6でもいけた希ガス。

117 名前:デフォルトの名無しさん mailto:sage [2006/02/20(月) 13:37:05 ]
434 名前:・∀・)っ-○●◎- ◆Pu/ODYSSEY 投稿日:2006/01/11(水) 00:05:58
論破されてやがるざまぁwwwwwwwwwwwwwwwwwwwww

118 名前:デフォルトの名無しさん mailto:sage [2006/02/20(月) 14:09:47 ]
>>115
意味ないね。その場合ってロードをプリフェッチすれば
ピーク性能を引き出せるのかな?

119 名前:100 mailto:sage [2006/02/20(月) 20:02:21 ]
金曜日にお世話になりました>100 です。
>101 殿のアドバイスを元に、改良版を作成して実験したところ、試行1回あたり
0.01msほど早くなりました(笑
#640×480サイズ、1万回試行の平均。
MMXレジスタ8本全部使って16ピクセル分1ループで処理するサンプルも実験
してみましたが(ループ回数削減を企図)、やはりほとんど変わりませんでした。

 処理画像サイズを大きくしても、0.1msほどの違いしか出ないことを考えると、
「メモリ速度がネックになる」という>103、>104 殿の指摘にハマっていそうです。
 他の作業指示が飛んできたので、現状でこれ以上の追求は出来なくなって
しまいましたが、メモリ速度や最適化の意義などについて深く考える良い機会に
なりました。折を見てまたいろいろ試してみたいと思います。

>116 殿
 かなりそれは魅力的な手段ですが……引き継いだ後に環境再構築できる人間が(ry


120 名前:97 [2006/02/21(火) 12:50:45 ]
>>111
いや言っている。
どちらかというと言語の標準仕様であってもらいたいね。
件の記法が正式採用されたら最適化エンジンは楽チンにベクトル化出来るし
SIMD使えないときでも依存関係の解析が楽になる。
処理が長いときはスレッド化だってイケる。

どれかの言語がこんな感じの機能を実装したら(あるいは約束したら)、
明日にでもその言語に乗り換えるね。

121 名前:デフォルトの名無しさん mailto:sage [2006/02/21(火) 13:18:37 ]
>>119
0.01msか。思ったより効かないな。
prefetchの代替ならmovを使うという手もあるが、この処理の要はmovntqだからな。
後で俺も試してみよう。

122 名前:デフォルトの名無しさん mailto:sage [2006/02/21(火) 13:58:35 ]
Win機でのprefetchはいろいろやったけどあまり効かなかった。
効果てきめんな人居る?

別のCPUでうまいこと使って爆発的に速くなった経験はあるから、
ちゃんとはまれば効果があることは理解してるんだけど失敗続き…

VTuneとかでメモリアクセスのパターンとか見れば何とかなるか
と評価版を試してみたけど結局うまく行ってない。残念無念

123 名前:デフォルトの名無しさん mailto:sage [2006/02/21(火) 14:03:39 ]
非実用コードで試しても、1割くらい速くなるだけだね。
キャッシュラインは64byteないとほとんど効かないと思う。



124 名前:デフォルトの名無しさん mailto:sage [2006/02/21(火) 14:23:50 ]
>>122
PGIの嘘っぽい最適化結果によると
ttp://www.softek.co.jp/SPG/Pgi/TIPS/amd64_em64t.html
だそうな。

125 名前:デフォルトの名無しさん mailto:sage [2006/02/21(火) 16:37:15 ]
PGIスレにぎわってないけど、ホントに性能出るもんかねえ?

intelでもオレのケースではまったく効果なかったし(性能クリ
ティカルな部分は全部SIMD化している)、iccで最適化
かけた性能はオレのasmコードにぜんぜんのよばねーし。

126 名前:デフォルトの名無しさん mailto:sage [2006/02/21(火) 17:05:03 ]
ハードウェアプリフェッチついてるから、
ソフトウェアプリフェッチの効果薄いのかもね。

メモリアクセスレイテンシ対策にはiccの
#pragma unroll(?)
は段数変えてみると結構効く場合があるね。


127 名前:デフォルトの名無しさん mailto:sage [2006/02/21(火) 21:34:42 ]
バタフライ演算が華麗に書けないのは痛いな。他のレジスタにコピーして
別に計算、マスクしてから元のレジスタに加算とか、ステップが余計にかかって
しょうがない。
二次元DCTをFCTで書いたものと、まともにDCTしたものを比べたら、普通の
DCTのほうが幾らか速かったorz
腕が悪い可能性も大だが。

V-Tuneなんつうブルジョアなものは持ってないので、visioでダイヤグラムを
書いて、ペナルティを極力食らわないように組替えてからソースを書きました
とさ。手動最適化マンセー。

128 名前:デフォルトの名無しさん mailto:sage [2006/02/21(火) 22:24:19 ]
shuffle命令やSSE3使ってる?


129 名前:デフォルトの名無しさん [2006/02/22(水) 10:48:20 ]
SSEすら使ってない。

お客は5、6年位前のスペックでも結構平気で使ってるからな。
SSE3対応の石にせよ、この国ではすでにデスクトップ市場を越えたノート市場で
最近出始めたばかりで、使えないことのほうが多い。

Intel Macあたりが対象なら、あんま考えなくていいけど。

まぁMMXまでは完全に存在を前提に書いたりするがな。
MMX非対応の石はどのみち絶対性能が不足するので切り捨ててる。

つか、SSE2/3って、本当にごく特殊な演算を除けば、MMXの有無程にはパフォーマンスに影響ないんだよな。


130 名前:デフォルトの名無しさん mailto:sage [2006/02/22(水) 11:00:13 ]
>>129
>SSE2/3って、本当にごく特殊な演算を除けば、MMXの有無程にはパフォーマンスに影響ない
同意

MMXでの高性能化に比べてSSE以降はかなりがっかりなのだ。
MMXと同程度に努力したが同じ率での高速化はしなかったよ。

掛け算に無符号が付いたMMX2は最初からやっとけと

131 名前:デフォルトの名無しさん mailto:sage [2006/02/22(水) 11:50:23 ]
ま、あれか。プログラム起動時にCPUの種類を判別して、それぞれに
最適なルーチンを走らせるというのが普通か。

132 名前:デフォルトの名無しさん mailto:sage [2006/02/22(水) 12:27:12 ]
手動最適化はMMXだけ使って
SSEはコンパイラに丸投げ

そんなシナリオを想定してある感じ

133 名前:デフォルトの名無しさん mailto:sage [2006/02/22(水) 13:04:07 ]
MMXはまぁ当然として、SSEはP3/AthlonXPからだっけ?
x86の浮動小数点命令は使いにくいからSSEでの最適化は欠かせないなぁ。
3D Now! の話題が全く無いのは互換性割り切るほど速度出ないからか。

>129
SSE2/3の命令ってmov系と高精度演算命令系以外になんかあんの?



134 名前:デフォルトの名無しさん mailto:sage [2006/02/22(水) 13:47:08 ]
>>133
MendocinoコアCeleronの載ったマシンとか現役で使ってる人が結構いるから
SSEも迂闊に使えないwww

もっとも、うちは基本的に整数演算か倍精度実数演算しか滅多に使わない
人なんで、パックド単精度ってそんなに有り難味が無い。
pmovmskbとかmaskmovqとかもそれなりに便利だけど、わざわざ別々の最適化コード
書いてディスパッチするだけの労力に見合った効果も得にくいんだよな。

> SSE2/3
ホラ、あるじゃないか。MMX/3DNOW!を無理矢理二つくっ付けた様な糞命令群が。
このへんは演算ユニットが128bit化するときのための布石と考えてるが。
てか、64bitになるとMMXもそろそろ要らなくなりそうな雰囲気。
飽和演算とか撹拌処理とかやらなくていいなら汎用ALU使ったほうが速度が出るんだよね。

135 名前:デフォルトの名無しさん mailto:sage [2006/02/22(水) 15:08:51 ]
>>100のコードと、>>119で使われたと思われるコードで測定してみた。@PenM
640*480*16で、43.7msと43.2msくらい。1%程度の違いしかない。
最初からL2ヒットであれば>119が倍近く速いので、やはりメモリネック。

ストアに対してprefetchntaを使うと30.8ms。効いてます(ライトスルーのP4では効かないかも)。
ていうかプリフェッチなんかせずにストアをmovntqにすると18.1ms(これはP4でもOKだと思う)。
単純な処理の割に、MMXが効かずSSE(MMX2)が効くというヤツであった。

>>119
仕事で使っているみたいだから無理だとは思うけど、>>100のコードのmovq [edi], mm0;の行を
_asm _emit 0x0f _asm _emit 0xe7 _asm _emit 0x07;//movntq [edi], mm0 のマシン語コード
このように書き換えればmovntqが使えますぜ。
俺の環境だと20.0ms。たった1行書き換えただけで倍以上速くなるのは気持ちいい♪


>>115
prefetchntaが最速だった。
ロードなしのmovntや、ストアなしのprefetchロード、というならもっと速いが、
ロードとストアを両立させようとすると、prefetchntaという結論になる。

136 名前:デフォルトの名無しさん mailto:sage [2006/02/22(水) 15:29:56 ]
>>134
>Mendocinoコア
めんどっちーの、と読むのか?

137 名前:デフォルトの名無しさん mailto:sage [2006/02/22(水) 19:52:50 ]
略してマンコア

138 名前:デフォルトの名無しさん [2006/02/23(木) 20:53:08 ]
>135 殿
 アドバイスありがとうございます。
 実験してみましたところ、おおよそ速度が4倍にアップしました。
 こりゃすげえ! と思ったのですが、上長には却下されました。
『だれもわからねぇYo!』だそうで。
 さすがにMMX2まで扱おうとすると、VC6ではやりづらいですね。
上長の上の人に結果まとめてレポしてみて、環境更新するよう具申してみることにします。

 ちなみに、こちらの環境で一番速かったのは、>101殿のアドバイス
を受けたもの(>119報告のもの)の改造版でした。

void test4( void *dst, const void *src, int size )
{ int size2 = size >> 2;
  if(size2 != 0){ __asm{
     mov      edi,  dst;
     mov      esi,  src;
     mov      ecx,  size2;
   loop_mp:
     movd     mm0,  [esi];
     punpcklbw  mm0,  mm0;
     movq     mm1,  mm0;
     punpcklbw  mm0,  mm0;
     punpckhbw  mm1,  mm1;
     _asm _emit 0x0f _asm _emit 0xe7 _asm _emit 0x07;
     _asm _emit 0x0f _asm _emit 0xe7 _asm _emit 0x4f _asm _emit 0x08;
     add      esi,  4;
     add      edi,  16;
     sub      ecx,  1;
     jnz       loop_mp;
     emms;
 }}
}

139 名前:デフォルトの名無しさん mailto:sage [2006/02/23(木) 21:14:55 ]
MMX2って何?SSEで入れられた整数演算?

140 名前:・∀・)っ-○●◎- ◆Pu/ODYSSEY mailto:sage [2006/02/23(木) 21:38:09 ]
もともとはSSEの旧い仮称だった気が。

今はへるみ氏あたりが初代AthlonでサポートされたEnhanced 3DNOW!とで
共通で使える拡張命令(要するにSSEのMMX整数演算拡張)を総称して
そう言ってるような。

案外午後な人書き込んでるかもしれんね。

141 名前:デフォルトの名無しさん mailto:sage [2006/02/23(木) 22:22:04 ]
浮動小数点形式にすればバタフライ演算は可能になるが、そのかわり
一度に演算できるデータは少なくなる。
16bit整数でバタフライ演算すれば同時に処理できるデータは8点に増えるが、
同じレジスタ内に0以上1未満の整数値(シフト処理したもの)と1以上の
整数値が混在する場合は、バタフライ演算で同時に演算できない。
該当するデータはいったん別のレジスタで処理しなければ成らないため
ステップ数が増える。

精度を保って処理したいなら単精度小数点などで処理するが、リアルタイム
性能を追求するなら整数で処理するしかないかな、と。
まぁ、どうせインテルは本当に便利な命令は用意しない方針のようなので。

142 名前:デフォルトの名無しさん mailto:sage [2006/02/23(木) 22:53:27 ]

ソフトウェアパイプライニングとか
手でやってる?コンパイラまかせ?
x64だとレジスタ数も違うし、そもそも
CPUごとにレイテンシ等変わって面倒だよね?


143 名前:・∀・)っ-○●◎- ◆Pu/ODYSSEY mailto:sage [2006/02/23(木) 23:01:45 ]
Athlon系はレイテンシが長いからL/S頻度上げてでも並列化汁
PenMは全般にレイテンシ短いから程々でヨシ
NetBurstはパイプラインの長さの分OoOが強力だからあんまり何も考えないほうが
かえって良かったりするかも。

という風に把握している



144 名前:デフォルトの名無しさん [2006/02/24(金) 08:45:35 ]
>>142
JIT付きの実行環境が欲しくなるなあ

145 名前:・∀・)っ-○●◎- ◆Pu/ODYSSEY mailto:sage [2006/02/24(金) 21:27:24 ]
っ[ドトニート]






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<141KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef