1 名前:デフォルトの名無しさん [04/05/28 22:00] どうぞ
413 名前: ◆0uxK91AxII mailto:sage [2007/08/26(日) 13:46:03 ] >>412 disassembleしてみたまえ。
414 名前:デフォルトの名無しさん mailto:sage [2007/08/26(日) 14:50:52 ] >>413 eaxって書いたところがmm0になってました。 インラインアセンブラのバグ? VC6のころからそうなのに VC8でも放置してるのはなんか理由があるのかな。
415 名前:・∀・)っ-○◎● mailto:sage [2007/08/26(日) 17:02:22 ] mm0もeaxも3ビット表現の 0 だもの。 汎用・FP/MM・XMMのレジスタ指定はopcodeで決まるから
416 名前:デフォルトの名無しさん mailto:sage [2007/08/26(日) 17:31:27 ] >>415 逆アセしてmm0に見える理由がそれだとしても、アセンブラの文法 としてeaxって書くべきではないところに、そう書いてエラーにしない のはおかしいと思いませんか?
417 名前:・∀・)っ-○◎● mailto:sage [2007/08/26(日) 17:32:25 ] movd eax mm0と movd mm0, eax だとどうなるかな。opcodeで区別してるはずだが
418 名前:デフォルトの名無しさん mailto:sage [2007/08/26(日) 17:44:31 ] その命令は見た目どおりに動くので、特にいうことはありません。
419 名前:デフォルトの名無しさん mailto:sage [2007/08/30(木) 17:09:15 ] >>404 AMDが発表したSSE5で独立シフト量ができるようになるね。 SIMDのローテート命令まで追加されてる。 developer.amd.com/assets/sse5_43479_BDAPMU_3-00_8-27-07.pdf
420 名前:デフォルトの名無しさん mailto:sage [2007/09/02(日) 04:12:12 ] もう32bit fpと整数はAltiVec互換にしてくれよ AltiVecからSSEに仕方なく移ったマカーな俺にはSSEは使いにくすぎる
421 名前:デフォルトの名無しさん mailto:sage [2007/09/02(日) 04:17:13 ] でもload/storeのアラインメントの扱いが楽なのはちょっといいと思った
422 名前:・∀・)っ-<コ:彡- mailto:sage [2007/09/04(火) 07:15:10 ] SSE4.1でXMM-汎用レジスタ間のデータ出し入れが簡単になるからシフトやローテートは我慢。
423 名前:デフォルトの名無しさん mailto:sage [2007/09/05(水) 23:49:14 ] >>422 もー出てるなら我慢できるけどさ、まだ出てないじゃん。
424 名前:・∀・)っ-<コ:彡- mailto:sage [2007/09/06(木) 00:47:16 ] それ言っちゃうとBulldozerはおろかBarcelonaすら出てないが
425 名前:デフォルトの名無しさん mailto:sage [2007/10/19(金) 17:12:17 ] MMXのpmull, pmulhはどういう使い方が想定されているのでしょうか? なんか使いにくそうに思えるのですが……。
426 名前:デフォルトの名無しさん mailto:sage [2007/10/19(金) 19:17:59 ] >>425 pmull : 16 bit で済む時 pmulh : 小数部 16 bit の固定小数点乗算したい時
427 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2007/10/20(土) 01:26:21 ] xbyakを魔改造するか
428 名前:デフォルトの名無しさん mailto:sage [2007/10/24(水) 22:36:46 ] IA-32 SIMDリファレンスブック<下> www.cutt.co.jp/book/4-87783-170-7.html SSSE3まで SSE4はない
429 名前:デフォルトの名無しさん mailto:sage [2007/10/24(水) 22:52:02 ] だから高いって。
430 名前:デフォルトの名無しさん mailto:sage [2007/10/25(木) 01:49:44 ] ぼったくりでそれか。マジいらん。
431 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2007/10/25(木) 01:55:23 ] SDK for 45nm Next Generation Intel Core 2 Processor Family and Intel SSE4 にSSE4.1/4.2のマニュアル一式とエミュレーションDLLがついてるからそれで十分。
432 名前:デフォルトの名無しさん [2007/10/27(土) 05:20:50 ] 総和を求めるなど、一つの変数が共通の場合、SSEを使って計算するCコードを教えてください
433 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2007/10/28(日) 02:23:19 ] 総和なら簡単じゃん __declspec(align(16)) float a[100]; float dest; //SIMD化前 for (int i = 0; i < 100; i++) { sum += a[i]; } //SIMD化後 __m128i sumx = { 0.0f,0.0f,0.0f,0.0f }; for (int i = 0; i < 100; i++) { sumx = _mm_add_ps(sum, *(__m128*)&a[i*4])); } sumx = _mm_hadd_ps(sumx, sum); sumx = _mm_hadd_ps(sumx, sum); _mm_store_ss(sum, sumx);
434 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2007/10/28(日) 02:24:14 ] 訂正 //SIMD化後 __m128i sumx = { 0.0f,0.0f,0.0f,0.0f }; for (int i = 0; i < 100; i+=4) { sumx = _mm_add_ps(sumx, *(__m128*)&a[i])); } sumx = _mm_hadd_ps(sumx, sum); sumx = _mm_hadd_ps(sumx, sum); _mm_store_ss(sum, sumx);
435 名前:デフォルトの名無しさん mailto:sage [2007/10/31(水) 21:29:38 ] movqに対応する組込み関数ってないん?
436 名前:デフォルトの名無しさん mailto:sage [2007/10/31(水) 21:57:18 ] _mm_loadl_epi64
437 名前:デフォルトの名無しさん mailto:sage [2007/10/31(水) 22:03:36 ] Σ(・ω・ノ)ノエッ
438 名前:デフォルトの名無しさん mailto:sage [2007/11/01(木) 00:19:03 ] __m128i _mm_loadl_epi64(__m128i*) __m128i _mm_move_epi64(__m128i) void _mm_storel_epi64(_m128i*, __m128i)
439 名前:デフォルトの名無しさん mailto:sage [2007/11/01(木) 02:28:07 ] sse4のベンチ見てるとちょっと心配になってくるな。
440 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2007/11/01(木) 23:00:54 ] >>435 MMXのは無い。 __m64 mm0 = a[i]で既にロードに展開される。てか、コンパイラ任せ。
441 名前:デフォルトの名無しさん mailto:sage [2007/11/14(水) 19:03:24 ] x86の話なんですが 64ビット整数のグローバル変数1つを操作する関数が 頻繁に呼ばれるプログラムを作っています。 アセンブラ見ると、32ビットずつ操作しているようなんですが これをMMXを使っていっぺんに操作するようにすれば、高速化しますか? 高速化するなら、MMX勉強してみようかなと思ってるのですが。
442 名前:デフォルトの名無しさん mailto:sage [2007/11/14(水) 19:57:23 ] しません
443 名前:デフォルトの名無しさん mailto:sage [2007/11/14(水) 19:59:23 ] andとかorとかビット演算だけなら可能性がないとも言えない。
444 名前:デフォルトの名無しさん mailto:sage [2007/11/14(水) 22:10:28 ] >>441 double でやればー?
445 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2007/11/14(水) 23:38:44 ] 関数コールのインライン化のほうがまだ効果あるかもな
446 名前:デフォルトの名無しさん mailto:sage [2007/12/22(土) 23:14:35 ] 2つの4byteのデータを先頭から任意の ビット数一致しているかチェックするのに SSEって有効に使えそう?1ビットずつチェック とかアホ過ぎて uint32_t chk_bit(uint32_t master, uint32_t src, uint32_t bit){ この中どうしよう。 }
447 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2007/12/22(土) 23:53:57 ] 【この中】 return ((master ^ src) >> (32 - bit)) != 0;
448 名前:デフォルトの名無しさん mailto:age [2007/12/24(月) 00:16:33 ] xmmレジスタを128bit intとして使う場合, あるbitが立っているかどうかを高速に調べる方法はありませんか? SSE4.1でptst命令が導入されますが,それまで待ってられません.
449 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2007/12/24(月) 00:30:38 ] xmm0に調べたい値ががあるとすれば movdqa xmm1, [pattern] movdqa xmm2, xmm0 pand xmm2, xmm1 pcmpeqb xmm2, xmm1 pmovskb eax, xmm0 test eax, eax でeaxが0以外ならビットが立ってる。
450 名前:ヽ>´∀`<,,)っ━━━━━━┓ mailto:sage [2007/12/24(月) 00:31:51 ] pmovmskbに訂正してくだしあ><
451 名前:デフォルトの名無しさん mailto:sage [2007/12/24(月) 00:46:27 ] THX やはりpmovmskbで移すしかありませんか... Nehalemまでは64bit int x 2でやっとくのが吉?
452 名前:デフォルトの名無しさん [2007/12/24(月) 11:21:12 ] ptestはPenrynじゃね?
453 名前:デフォルトの名無しさん mailto:sage [2007/12/24(月) 13:14:13 ] LARGE_INTEGER otime, ntime; 〜略〜 double dt = (double)((ntime.QuadPart - otime.QuadPart) * (1000.0f / f.QuadPart)); をSSE使ってVC8のインラインアセンブラで書くとどうなりますか?
454 名前:デフォルトの名無しさん mailto:sage [2007/12/24(月) 19:38:49 ] どう考えてもスカラ演算だよね
455 名前:デフォルトの名無しさん mailto:sage [2007/12/24(月) 20:04:35 ] 64bit整数を64bit浮動小数点数に返還するSSE命令は 64bitモードにしかありません VCでは64bitモード用のプログラムにインラインアセンブラは使えません
456 名前:ヽ>´∀`<,,)っ━━━━━━┓ mailto:sage [2007/12/24(月) 20:30:13 ] *intrin.hのマニュアルを見ればいいと思うが
457 名前:デフォルトの名無しさん mailto:sage [2007/12/24(月) 20:32:45 ] SSEで書く利点なくね?
458 名前:ヽ>´∀`<,,)っ━━━━━━┓ mailto:sage [2007/12/24(月) 20:37:16 ] 無いな
459 名前:デフォルトの名無しさん mailto:sage [2007/12/24(月) 20:58:49 ] 書けても手間損
460 名前:デフォルトの名無しさん mailto:sage [2007/12/24(月) 21:00:24 ] ファイヤーウォール作る時に パケット解析するのにSSE使っても 手間になるだけ?
461 名前:ヽ>´∀`<,,)っ━━━━━━┓ mailto:sage [2007/12/24(月) 21:02:06 ] そろそろテンプレ作ったほうがいいんじゃないの。 SSEは大量のデータに同じ処理をかけるときにこそ効果を発揮するんであって 細かい所は従来のx86命令のほうがむしろ速い。
462 名前:ヽ>´∀`<,,)っ━━━━━━┓ mailto:sage [2007/12/24(月) 21:03:24 ] >>460 そういうのに向いてるって話は聞いたことがない。
463 名前:デフォルトの名無しさん mailto:sage [2007/12/24(月) 21:55:34 ] 単一の64bitや128bit値を何回も計算するときは?
464 名前:デフォルトの名無しさん mailto:sage [2007/12/24(月) 21:57:38 ] 汎用レジスタに納まらないサイズ弄るなら効果あるんじゃないの?
465 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2007/12/24(月) 22:04:42 ] アレはあくまで32ビット値を4つ同時に扱うものであって、多倍長扱うならむしろ64ビットモードで汎用レジスタベースでやったほうがいい。
466 名前:デフォルトの名無しさん mailto:sage [2007/12/24(月) 22:15:44 ] ( ・∀・)つ〃∩ ヘェーヘェーヘェーヘェーヘェー
467 名前:デフォルトの名無しさん mailto:sage [2007/12/25(火) 17:49:27 ] PADDQとかの事だろうけどC2Dでもレイテンシ2だしね 実装はcarry selectあたりだろうか
468 名前:451 mailto:sage [2007/12/26(水) 11:18:07 ] >>452 遅レスだが ptestはSSE4.1で,PenrynはSSE4じゃなかった?
469 名前:デフォルトの名無しさん mailto:sage [2007/12/26(水) 11:52:30 ] SSE4はSSE4.1とSSE4.2の両方を含む呼称(正確には、という事になった) Penrynは4.1のみ Nehalemは4.1と4.2の両方 >>452 で合ってるんじゃねーの?
470 名前:451 mailto:sage [2007/12/26(水) 13:20:32 ] >>469 どうもその様ですね,THX. ttp://pc.watch.impress.co.jp/docs/2007/0925/hot507.htm Penrynならそれほど待たなくて済むなぁ,どうしよう.
471 名前:451 mailto:sage [2007/12/26(水) 13:22:02 ] >それほど待たなくて済むなぁ これは価格が手頃になるのを,って意味です
472 名前:デフォルトの名無しさん mailto:sage [2007/12/26(水) 13:25:45 ] 64bit浮動小数点数の配列があったとき絶対値が最大の要素を 求めたいのですがSSE2を使って高速にできるでしょうか? 普段はVC++を使ってますがより高速化できるならアセンブラ もつかってみようかと考えてます。OSはVista(64bit)です。
473 名前:デフォルトの名無しさん mailto:sage [2007/12/26(水) 13:54:20 ] >>472 x64用ののVC++だとデフォルトでSSE2を使うようになっている。 下のを cl /c /O2 /FAsc test.c でコンパイルして、test.cod を見てみるとまあまあのコードが生成されているぞ。 double maxabs(double array[], int size) { double ans = 0.0; for (int i=0; i<size; i++) ans = __max(ans, abs(array[i])); return ans; }
474 名前:デフォルトの名無しさん mailto:sage [2007/12/26(水) 18:30:53 ] >>473 Cだと「for (int i=0;」のところでエラーになるので #include <cmath> #include <cstdlib> を付け加えてCPPファイルにしてコンパイルしてみました。 movsdx andpd comisd などが使われていますね。これがSSE2かな? でもこれが本当に高速なコードかどうかはわからないですね。 インテルでMKLというライブラリを出してますがこれはすごいですね。 試したのは行列計算の一部だけ(LU分解)ですが数値計算の本に載っている プログラムをVC++でコンパイルしたものより5倍ぐらい高速です。 数学レベルで新アルゴリズムを開発した可能性は低いので実装レベル の技術が高いと思うのです。 5倍の差は大きいのでSSEなどを勉強して何とか近づきたいのですが 大変かな?
475 名前:デフォルトの名無しさん mailto:sage [2007/12/26(水) 18:38:45 ] dou you make correlated random number?
476 名前:451 mailto:sage [2007/12/26(水) 20:38:30 ] >>472 P4用でちょっと古いけど 「ストリーミング SIMD 拡張命令 2(SSE2)を使用した、倍精度浮動小数点ベクトルの最大/最小要素とそのインデックスの検出」download.intel.com/jp/developer/jpdoc/w_max_app_j.pdf
477 名前:472 mailto:sage [2007/12/26(水) 23:15:38 ] >>476 やりたいのは絶対値の最大なのでちょっと違うけどなかなか参考になります。 最大と最小をもとめて絶対値の大きな方をとる方法と 絶対値を計算しながら最大をもとめる方法がありますね。 まあこの辺はいろいろ実験してみないとどれがいいのかわからないですね。
478 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2007/12/27(木) 02:18:53 ] >>473 VC++だとmaxsdしか使わない予感。 >>473 ベースで、arrayの要素が偶数個で128ビット境界にあってるの前提ならこんな感じ たぶんSSE3くらいは使えるよね?たいしたことに使ってないけど。 #include <pmmintrin.h> double maxabs(double array[], int size) { static const union { __m128d pd; __int64 a[2]; } mask = { 0x7FFFFFFFFFFFFFFFi64, 0x7FFFFFFFFFFFFFFFi64 }; double ans; __m128d ans_pd = { 0.0, 0.0 }; for (int i = 0; i < size; i+= 2) ans_pd = _mm_max_pd( ans_pd, _mm_and_pd(mask.pd, *((__m128d*)&array[i])) ); ans_pd = _mm_hadd_pd(ans_pd, ans_pd); _mm_store_sd(&ans, ans_pd); return ans; }
479 名前:デフォルトの名無しさん mailto:sage [2007/12/27(木) 23:05:22 ] >>474 SIMD化の方が簡単で面白そうだから目につきやすいんだけど、そこは最後の手段なんだよね。 配列同士の四則演算では極力全ての演算をまとめて行って、代入を1回で済ます。 行列なんかの三次元的なループはキャッシュに入る長方形のブロック単位で処理をする。 そういうところが出来てればSIMD化しなくても前者で最大2倍くらい、後者は計り知れない程速くなる。
480 名前:474 mailto:sage [2007/12/28(金) 23:06:10 ] >>479 気持ちはわかるけど具体的にはどうやるのかな? 短いので高速化したいプログラムをアップしてみる。 #include <cmath> double LU(int n, double** a, int* ip) { int i,j,k,ii,ik; double t,u,det,*w; w=new double[n]; for(k=0;k<n;k++){ ip[k]=k; for(j=0,u=0;j<n;j++){ t=fabs(a[k][j]); if(t>u) u=t; } if(u==0){ delete[]w; return 0; } w[k]=1/u; } det=1; for(k=0;k<n;k++){ u=-1;
481 名前:474 mailto:sage [2007/12/28(金) 23:08:38 ] 続き for(i=k;i<n;i++){ ii=ip[i]; t=fabs(a[ii][k])*w[ii]; if(t>u){ u=t; j=i; } } ik=ip[j]; if(j!=k){ ip[j]=ip[k]; ip[k]=ik; det=-det; } u=a[ik][k]; det*=u; if(u==0){ delete[]w; return 0; } for(i=k+1;i<n;i++){ ii=ip[i]; t=(a[ii][k]/=u); for(j=k+1;j<n;j++) a[ii][j]-=t*a[ik][j]; } } delete[]w; return det; } 最後のforループが3重ループなのでこの付近が一番スピードに関係してそう。
482 名前:デフォルトの名無しさん mailto:sage [2007/12/28(金) 23:33:40 ] キャッシュ効率上げればかんり高速化しそうだね
483 名前:479 mailto:sage [2007/12/29(土) 23:23:23 ] 恥ずかしながらLU分解はやった事無いんだけど 3重のループでa[ii]のラインはiに依存して切り替わり、 a[ik]のラインはkに依存して切り替わるでしょ。 a[ik]のラインはkにつき1度しか切り替わらないからキャッシュにずっと入ってるけど、 a[ii]のラインはkが同じでもiが変わったら切り替わってしまう。 a[ii]のラインは最大k回アクセスがあるから、出来れば切り替えたく無い。 そこで折衷案をとって、a[ik]をもう少し頻繁に切り替える代わりにa[ii]をもう少しゆっくり切り替わるようにバランスを取る。 バランスを取るというのはどういう事かと言うと、 二次元の処理で1000x1000の要素があった時に 1ラインずつ処理するのではなく例えば100x100のマスが10x10個あるものとして処理する。 (0, 0)-(999, 0)を処理してから(0, 1)-(999, 1)の処理をするんじゃなくて、 (0, 0)-(99, 0)まで処理して(0, 1)-(99, 1)...(0, 99, 99, 99), (100, 0)-(199, 0)のような処理の仕方。 今回はループが3重だから、書き換えると6重のループになって頭は最高にこんがらがる。 しかもラインがipによって入れ替わるみたいだから、こういう手法が使えるのかよく分らない。ごめん。 ipがどう変わるかを事前に必要なライン数分計算出来ればいいんだろうけど。
484 名前:474 mailto:sage [2007/12/30(日) 21:31:17 ] >>483 コメントありがとうございます 少し詳細に480のプログラム(LU1)と intelのMKLを使った場合(LU2)とをテストしました。 サイズ(n) LU1(VC++) LU2(MKL) 比率 4 0.218μs 1.140μs 0.191 8 0.796μs 2.680μs 0.297 16 4.087μs 7.460μs 0.548 32 0.0246ms 0.0204ms 1.21 64 0.174ms 0.0656ms 2.65 128 1.31ms 0.271ms 4.83 256 10.2ms 1.435ms 7.11 512 82.4ms 9.13ms 9.03 1024 780ms 66.1ms 11.8 2048 7.58s 0.501s 15.1 4096 60.9s 3.79s 16.1 8192 486.5s 29.9s 16.3 CPU:intel Q6700(3.4GHz) サイズが小さい場合はLU1でもキャッシュの利用効率が高いはずですが 予想どうりLU2との差が小さくなりnがごく小さいときは逆転しています。 たぶんLU2は複雑なやっていてそのため遅くなっているのでしょう。 nが非常に大きくなるとLU1はキャッシュ効率が悪いためLU2に大差をつけられてしまってます。 高速化をめざすならSSEの最適化を考える前にキャッシュ効率を上げる工夫をすべきですね。 となると483のような多重ループのブロック化が必然となるか? まあ、難しそうなので具体的な方法は少し考えてみます。 うまいアイデアがありましたらまたコメントください。(ややスレ違いになりつつあるが)
485 名前:デフォルトの名無しさん mailto:sage [2007/12/30(日) 22:03:51 ] ここは一応拡張命令のスレだからねえ。 もし移動するならここかな? ttp://pc11.2ch.net/test/read.cgi/tech/1177808054/l50
486 名前:デフォルトの名無しさん mailto:sage [2007/12/30(日) 22:07:51 ] ソフトウェア・プリフェッチの話を絡めつつやれば スレ違いにならなずに済むか。
487 名前:デフォルトの名無しさん mailto:sage [2008/01/16(水) 18:30:07 ] xmm の not を一命令で求める方法はありませんか? ~0 との xor は無しで
488 名前:487 mailto:age [2008/01/16(水) 20:45:05 ] 上げときます
489 名前:デフォルトの名無しさん mailto:sage [2008/01/16(水) 21:28:47 ] pandnでもダメだよな。 そうなると、周りの命令と絡めて実質的に1命令で済ますことを考えるくらいか。
490 名前:デフォルトの名無しさん mailto:age [2008/01/17(木) 00:08:24 ] 無理っぽいねぇ.all 1 の定数を read することを考えれば, cmpeq xmm0,xmm0 で all 1 を作る方が速いか?
491 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/01/17(木) 00:58:10 ] all 1をロードだとレジスタリネーミングされるので先行実行できる可能性がある。 ケースバイケース。
492 名前:デフォルトの名無しさん [2008/02/19(火) 10:43:09 ] メディアンフィルタを作成したいのですが、 コンパイラがSSEを使いやすいコードはどのように書いたらよいのでしょうか?
493 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 07:38:55 ] メディアンフィルタで自動ベクトル化は難しいなあ。 ソートアルゴリズムをGPUでやるやつみたいに直線的なものにすればやってくれない事は無いけど。 とにかく一番内側のループがベクトル同士の演算になるように心掛ける事。
494 名前:デフォルトの名無しさん mailto:sage [2008/06/19(木) 00:27:56 ] 行列計算をSSEで行った場合の 解説サイトしらないっすか?
495 名前:デフォルトの名無しさん mailto:sage [2008/06/19(木) 03:21:26 ] www.google.co.jp/search?num=100&q=%E8%A1%8C%E5%88%97%E8%A8%88%E7%AE%97%E3%82%92SSE
496 名前:デフォルトの名無しさん mailto:sage [2008/06/19(木) 22:39:47 ] a1=3.1 a2=4.0 a3=5.5 a4=6.1 r1 = a1^2 + a2^2 + a3^2 - a4^2 r2 = a1+a2 - a3*a4 +a1+a3 + a2*a4 r = r1+r2 こんなのSSEで解きたいんだけどどうすればいいんだろう
497 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 16:25:20 ] dvec.hの cmpeq()した結果が全て0かどうやって判別するの?
498 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 20:26:50 ] if ( _mm_movemask_pd(cmpeq(a, b)) == 0 )
499 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 23:31:44 ] む〜〜〜 倍精度の絶対値はどうすれば求まるの?
500 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 00:08:16 ] 学校の勉強か?ちったあ頭使えよ。 方法1(ロード無し): // a = a < 0 ? -a : a; F64vec2 z = _mm_setzero_pd(); a = select_lt(a, z, z-a, a); 方法2(ロード有り): static const __int64 _0x7FFFFFFFFFFFFFFFLL = 0x7FFFFFFFFFFFFFFFLL; F64vec2 m(*(double *)&_0x7FFFFFFFFFFFFFFFLL); a &= m;
501 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 00:11:01 ] 間違った。mは static const F64vec2 m = 以下省略
502 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 00:17:45 ] >>500 あーそういうのがあるのですね 何分あほ過ぎて、あきれてるかもしれませんがどうもすいません。
503 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 01:06:49 ] いいってことよ。 ちなみに絶対値の処理がループに入っていて比率が高い場合はロード有り、 絶対値を取る負荷が低いならロード無しが効率的。 ところで最近rcp_nr()やrsqrt_nr()の精度の低さを嘆いていて もう一段階計算するか素直にdivpsを使うか考えてたんだが ググってみるとdivpsとsqrtpsって最近は6 cycleなのな。typoじゃないのか?速すぎる。 なんかrsqrt_nr()はともかくrcp_nr()って要らない子な気がしてきた。 そもそも何故rcpps, rsqrtpsでVMXみたいに12ビット用意しなかったのかと問いつめたい。 プロセッサは日々速くなるんだから12ビットが最初は大きすぎでも用意するべきだったろう。
504 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 10:06:41 ] 6 cycleというのは、2.0 で割るみたいな単純なケースだけじゃないの?
505 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 10:39:18 ] 0除算ってどう扱うべきなの? 常にチェックするのかな
506 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 11:39:56 ] >>504 情報が古いが248966.pdfを読んでも13 cycleだぞ。これでも十分速過ぎるだろ。 ちょっと前まで40 cycleだったのに。 こりゃ中では12bitのrcppsを持ってるな。逆数取って精度上げが1回で済めば13 cycleでも納得出来る。 >>505 0除算は数学上定義されていない。 プログラムとか関係なく、机上で数式書いた時点でつっこむべきだ。 定義されていないので、当然答えは自分で用意する事。 1. 0で除算する時点で数式が間違っていたと認識し、方法を改める。 2. 除数が0にならないようなロジックにする。 3. 除数が0になった場合の回避策を設ける。 3-1. c = a / (b + 0.001) のようなかさ上げを行う。 3-2. c = a / max(b, 1) のような下限を設ける。 3-3. c = b == 0 ? 0 : a/b のような特別な取り扱いを行う。 4. 結果がNANかを調べて後から計算に失敗している事を認識する。 3はプログラムに組み入れる事になる。3-2と3-3は当然事前に分かればそこで取り扱えばいいし、直前まで分からなければ常にチェックする。 処理によっては無理に回避するよりも4が重要な場合もある。
507 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 12:42:58 ] gccに#include <dvec.h>ってないんだな icc買うしかないか
508 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 13:32:06 ] >>505 常にチェックしなくても、__try { } で囲んで、 0除算例外を __except() で受ける方法もあるよ。 例外を発生させるようにfldcwやldmxcsrで設定する必要があるけど。
509 名前:デフォルトの名無しさん [2008/06/25(水) 14:48:40 ] 複数のスレッドで同時にMMX命令を使う場合に スレッドごとにemmsを呼ぶ必要はありますか? それとも以下のように、複数のスレッドから抜け出た後に 一回だけemmsを呼べばOKですか? #pragma omp parallel for for (int i = 0; i < hoge; i++) { // ここでMMXを使用 (x87命令は使わない) } _mm_empty(); // emmsはこの一回でOK?
510 名前:509 mailto:sage [2008/06/25(水) 16:10:01 ] 何かあったら怖いので スレッドごとにemmsを呼び出すことにしました。
511 名前:デフォルトの名無しさん mailto:sage [2008/06/26(木) 02:27:18 ] マルチスレッドでMMXは未対応だけどな
512 名前:デフォルトの名無しさん mailto:sage [2008/06/26(木) 22:59:19 ] そのへんはOS依存じゃないの?
513 名前:デフォルトの名無しさん mailto:sage [2008/06/26(木) 23:10:16 ] いやSSEもMMXもマルチコアとマルチスレッド未対応だろ
514 名前:デフォルトの名無しさん mailto:sage [2008/06/27(金) 00:40:22 ] マルチスレッド未対応とはコンテキストスイッチへの対応のことを言っているの? MMX/3DNowはx87FPUとレジスタ兼用だから問題無いし、 SSEはFXSAVE/FXRSTORという専用命令があるから、これも問題なさそうだが。
515 名前:デフォルトの名無しさん mailto:sage [2008/06/27(金) 00:50:59 ] そうじゃねー マルチプロセスならコンテクストスイッチ時にSSE/MMXレジスタが 保存されるだろうがマルチスレッドは一つのプロセスの中で複数の スレッドを走らせるので汎用レジスタ退避しかない
516 名前:デフォルトの名無しさん [2008/06/27(金) 01:03:32 ] >>515 なにその糞環境? 晒してみ
517 名前:デフォルトの名無しさん mailto:sage [2008/06/27(金) 01:10:51 ] マルチスレッドの実装に依存する話だが 少なくとも Linux は大丈夫だったはず ダメな環境を俺も知りたい
518 名前:デフォルトの名無しさん mailto:sage [2008/06/27(金) 02:14:56 ] Windows 95とか? プロセス間でもだめだしそもそも(ry なんてツッコミはいやん
519 名前:デフォルトの名無しさん mailto:sage [2008/06/27(金) 02:31:10 ] >>515 1.>>514 に書いてあるように MMXレジスタ = x87レジスタ なのだから、 MMXレジスタが保存されないなら小数点演算も同様ではないのか。 2.特権ユーザでもない限りコンテクストスイッチを禁止できない。 さもなければ誰でもシステムを強制停止できてしまう。 (例:Windows 3.1) 制御できないとしたら、ではどのタイミングでレジスタを待避すればよいのか。 3.>マルチプロセスなら ... 中略 ... レジスタが保存される それで、マルチコア非対応になる理由はなに?
520 名前:デフォルトの名無しさん mailto:sage [2008/06/27(金) 03:03:41 ] シグナル(割り込み)とスレッドの区別の付かない人っているよね。 MMXのレジスタをFDPと共有させたのはOS側の対応を不要にするための 仕掛けだったのだけど今となってはやっちゃったって感じの仕組みと評価されている。
521 名前:519 mailto:sage [2008/06/27(金) 08:30:11 ] おっと、>>515 は対応してない(できない)と言っているのに、 2番ではやり方を聞いてしまってるな。 この質問は撤回するとして、代わりに3番に追加しておこう。 マルチコア非対応というのはマルチプロセッサ(ユニコア) ならばOKということか? SMT(ハイパースレッディング等)の場合はどうなのか。
522 名前:デフォルトの名無しさん mailto:sage [2008/06/27(金) 08:33:32 ] 基本的にシングルコアでのみ利用可能だ
523 名前:デフォルトの名無しさん mailto:sage [2008/06/27(金) 10:26:51 ] 新種のキチガイが暴れてるなwww 動かないっつーのが明記されてる資料出せやw
524 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 01:13:58 ] >>522 まず訂正するとユニコアなる単語はシングルコアの誤りだ。 そんで微妙に通じていないようだからもう一度聞くよ。 複数のシングルコアのCPUを搭載したマルチプロセッサの システムでMMX/SSEは利用可能なのか。 シングルコアなんだけど擬似的にマルチプロセッサの ように振る舞うSMT対応のCPUではどうか。 具体的に言うとHT有効なPentium4でMMXは使えるのか。 結論だけではなくて、理由を教えてもらいたいのだが。
525 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 01:31:34 ] 誤解のないように追記。 話を簡単にするためマルチプロセスの場合を聞きたい。 とりあえずこの件についてはマルチスレッドは保留で。
526 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 10:19:45 ] マルチプロセスの場合は 物理CPU1つだけで稼動する 物理CPU2つならそのうち1つだけ 4つならそのうち1つだけ
527 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 11:15:05 ] 脳内仕様はもういいよ、資料出せ資料を。
528 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/06/28(土) 14:34:24 ] >>496 亀レスだけど、どのへんが難しい? 単精度の場合だけど ;; r1 = a1^2 + a2^2 + a3^2 - a4^2 movaps xmm0, xmmword ptr [a1_a2_a3_a4] ;; a1, a2, a3, a4を並べておく movaps xmm1, xmm0 xorps xmm1, xmmword ptr [MASK_PPPN] ;; MASK_PPPN = { 0x00000000, 0x00000000, 0x00000000, 0x80000000 } ;; これで xmm1 = { a1, a2, a3, -a4 } になる dpps xmm0, xmm1, 0xF1 ;; 内積をとる ;; SSE4.1非対応ならdppsはこれで代替(SSE3必須) ;; mulps xmm0, xmm1 ;; haddps xmm0, xmm0 ;; haddps xmm0, xmm0 ;; SSE3が使えないなら・・・メンドイ・・・ ;; r2側は大して並列化が期待できないのでスカラでやってよし ;; r2 = a1+a2 - a3*a4 +a1+a3 + a2*a4 = a1+a1+a2+a3 + (a2-a3)*a4 movss xmm1, dword ptr [a1] addss xmm1, xmm1 ;; a1+a1 movss xmm2, dword ptr [a2] addss xmm1, xmm2 ;; (a1+a1) + a2 movss xmm3, dword ptr [a3] addss xmm1, xmm3 ;; subss xmm2, xmm3 ;; a2 - a3 mulss xmm2, dword ptr [a4] ;; (a2-a3)*a4 addss xmm1, xmm2 ;; r2 = = (a1+a1+a2+a3) + ((a2-a3)*a4) ;; 最後はこう addss xmm0, xmm1 ;; r = r1 + r2
529 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 14:36:05 ] >>526 回答は1件だけとか、理由を言っては駄目とかいう戒律でもあるの? >>515 でマルチスレッド非対応の原因として、コンテクストスイッチで レジスタの内容が保証されないことを挙げているが、一方で マルチプロセスならレジスタは保存されるとも言っている。 レジスタがきちんと保存されるならMMX/SSEを使わないプログラムと 何も違わないのに、なぜ一つの物理CPUに縛られるのか。 そんでどのCPUに固定的に割り当てられるのか。 そもそもその割り当てをするのはOS,CPU,アプリのうちどれ? OSかCPUならその名称、アプリならAPIの名称を教えてくれ。 すくなくとも最後の質問にだけは答えてほしい。
530 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/06/28(土) 15:03:54 ] >>524 HT Pen4はおろかCore 2 Quadでも余裕で使えてるから問題ない Core 2上だとXMMレジスタ使ったときのちょうど半分のスループットだけどな
531 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 15:05:48 ] >>526 あ、526では"物理CPU"と書いてあるね。 >>524 の質問には両方答えてあったのか。 すまない。 上の 2行目前半部分は、撤回する。 それと上でCPUなら名称を教えてくれと言ったがCPUのモデル名 ではなくて、振り分けを担当する機構の名称を聞きたかった。 (デコーダ、スケジューラ、実行ユニット等) 不注意な点が多いのは申し訳ない。 以後気をつける。
532 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/06/28(土) 15:05:53 ] そもそもコンテクストスイッチのときにMMX/FPステートの退避・復帰もやってるって
533 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 15:07:42 ] >>530 いや、使えるのは知っている。 ていうか使えないと主張しているのが1人いるだけ。
534 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/06/28(土) 15:11:31 ] 要するに www.intel.com/jp/download/index.htm IA-32 インテルR アーキテクチャー・ソフトウェア・デベロッパーズ・マニュアル、下巻: システム・プログラミング・ガイド なんかをちゃんと読んでない子が1名いるのね
535 名前:デフォルトの名無しさん mailto:sage [2008/06/29(日) 00:50:52 ] っつーか >MMX/FPステートの退避・復帰 をやってない処理系があるって主張してる子がいるんだろ
536 名前:デフォルトの名無しさん mailto:sage [2008/06/29(日) 01:17:44 ] >>535 仮にそんな処理系があったとして MMX/SSEがマルチスレッドに対応していないことには ならないよな。あくまでそのクソOSが対応してないだけであって。 つーか、バカバカしいので打ち切りの方向で。
537 名前:デフォルトの名無しさん mailto:sage [2008/06/29(日) 11:01:50 ] 他にも >>526 とか不可思議な主張してるから、どうしたら そんな世迷い言が出てくるのか聞いてみたくてね。 >>529 の回答がソフトウェアなら糞環境乙だし、ハードなら そんなもんあるわきゃないので、たぶん返答はないだろう けど、あっても次で終わるさ。 はぐらかすようならもう相手にしない。
538 名前:デフォルトの名無しさん mailto:sage [2008/07/08(火) 23:47:17 ] Core2って1CPUにつき レジスタ何本まで同時に使えるの?
539 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 00:07:06 ] わかるように質問してくれ CPUというのはコアなのかダイなのか? ニモニックから指定できるレジスタは固定だがどういう意味のレジスタなんだ?
540 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 00:11:48 ] xmmmmってやつ
541 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/07/09(水) 10:31:48 ] Core 2は3つの汎用ALUと1本のロード・1対のストアがある。 まさにその数分のレジスタが同時に使えるんだよ。 というのも、説明すると add eax, 3という操作があるとする。 実レジスタファイル上のeaxにマッピングされた領域から値をロードし、3を加えて またeaxに格納するってのを1サイクルでこなすのは実際は無理。 ショートカット用のレジスタ(要はアキュムレータ)に値を残すことによって、 次の命令ですぐにeaxの値を参照できるわけだ。 つまり1サイクルってのは実レジスタではなくアキュムレータの更新にかかるサイクル でしかない。 それ以上になると、実レジスタの読み書きの分待たされるので遅くなるわけ。 で、そのショートカットレジスタは実行ユニットの個数分だけある。 64bitでの性能が伸び悩むのも同じ理由だよ。 レジスタ個数が増えた分、レジスタ間オペレーションのインターリーブがしやすくなった。 でもそれによってショートカットの有効利用ができなくなる。 増えたレジスタを有効に使おうとすればするほど、実レジスタファイルへの読み書きが増え、 高速化が使えなくなる。 ちなみにNehalemでは若干改善されるみたいだが。 おそらくは同時にショートカットできるレジスタの個数が増えるのだろう。
542 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/07/09(水) 10:50:03 ] Core 2に限らずP6シリーズは伝統的にこの仕様なんでまあ細かいことは気にするな
543 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 22:28:30 ] つまり糞ってことだPowerPCと比較して 糞すぎるんだよなぁ
544 名前:デフォルトの名無しさん [2008/07/30(水) 21:25:16 ] 3D Nowの機能を使ったエンコードソフトなどありますか?
545 名前:デフォルトの名無しさん mailto:sage [2008/07/30(水) 22:18:57 ] 午後のコーダ mencoder ffmpeg
546 名前:デフォルトの名無しさん mailto:sage [2008/07/30(水) 22:57:31 ] >>509 の辺りをちらりと読んでアレレ?と心配になってしまいました。 でも、考えてみたら、タスクスイッチのときに、 今のコンテキストの情報(全レジスタ丸ごと)をメモリにコピーして スイッチ先タスクのコンテキストの情報を丸ごとメモリから読み込む訳だから、 コアが幾つあっても、タスクを実行するコアが入れ替わっても、 全然問題ありませんよね。
547 名前:デフォルトの名無しさん mailto:sage [2008/07/30(水) 23:16:18 ] 上によってタスク(スレッド)毎に別のレジスタセットをそれぞれ持っているような状態が作られる訳だから マルチタスク環境での MMX/SSE の使用は問題なくて、 ただ、スレッド開始時のコンテキストの情報がどうなっているかは、環境依存だろうから、 スレッド開始時にフラグを設定しなおした方がいいという事ですよね。 複数の CPU がある場合でも、タスクを実行する CPU が入れ替わらなければ、1 CPU の時と同じだし、 タスクを実行する CPU が入れ替わる場合でも何らかの形でコンテキストの情報丸ごとを受け継がなければ、 タスクの続きを正常に実行できなくなるわけだから、アプリケーションを作る プログラマが心配するような事では全くありませんよね。 なんかグダグダ書いてしまいって、見苦しいですよね。 御不快でしたら、スルーして下さいよね。
548 名前:デフォルトの名無しさん mailto:sage [2008/07/31(木) 11:11:55 ] うるせーペニス
549 名前:デフォルトの名無しさん mailto:sage [2008/08/01(金) 23:37:03 ] 8bit単位のシフトつけてくれ 明日までに欲しい
550 名前:デフォルトの名無しさん mailto:sage [2008/08/09(土) 16:28:29 ] 32bit幅の配列があり、 指定の下位nビット(1 <= n <= 32)以外のビットが立っていないときに、 その配列をnビット幅の配列としてメモリ上にギチギチに詰める& 詰めたものを32bit幅の配列に戻す、ということをやりたいです。 詰めるフォーマットは自由で、 詰め元・復元先について先頭のalignmentは揃えられます。
551 名前:デフォルトの名無しさん mailto:sage [2008/08/09(土) 16:53:05 ] そうですか。
552 名前:デフォルトの名無しさん mailto:sage [2008/08/09(土) 16:57:05 ] そうですね
553 名前:デフォルトの名無しさん mailto:sage [2008/08/10(日) 03:17:26 ] やればぁ
554 名前:,,・´∀`・,, mailto:sage [2008/09/01(月) 11:12:38 ] >>343 PowerPC(970以降)は命令間レイテンシが大きいからそれはそれで 隙間埋めるのが大変なんだがな。 1回だけ使うデータのロードだけでも1命令分使っちゃうこととか、 32ビット即値をレジスタにセットするのにも2命令かかったりとか、 いざ使ってみるとパフォーマンスにかかわる制約が多すぎる。 Int/FP/SIMD各32本とレジスタ本数が多いのが逆に災いして レジスタリネーミングそのものも弱いから、高速化のためには レイテンシ隠蔽のため静的なアンロールに費やされることになり、 結果的にはx86に対するレジスタ本数差分の優位すら覆されてしまう。 ジョブズの「今までの○倍」ってプレゼンもあながち誇張でもない。 ものによっては確かにそれくらいIntel CPUのほうが性能が出る。 命令セットは汚く論理リソースは限られてるが、その分だけ逆に アグレッシブな動的最適化技術が比較的有効に働くからね。 Java仮想マシンがスタックマシンなのだって、スタック構造は 並列度を抽出しやすいから。また、論理レジスタが少ないほど アウトオブオーダ・レジスタリネーミングのリソース管理が楽。 もちろん、静的な最適化で事足りるならそれに越したことはないんだが 実行ステージのパイプラインが深くなったりするたびに再コンパイル (最悪の場合再コーディング)してられないなど、「コード資産」 という名の制約もあるからね。 Intelのx86は新命令を取り入れつつも、既存のコードもコンパイル しなおさなくてもある程度は速く走ることを主眼に改良してきたから、 いろんな処理を無難にこなせるわけだ。
555 名前:,,・´∀`・,, mailto:sage [2008/09/01(月) 11:13:26 ] >>543 の間違い。しかも亀
556 名前:デフォルトの名無しさん mailto:sage [2008/10/01(水) 14:05:22 ] PPC信者に触っちゃいけません
557 名前:デフォルトの名無しさん mailto:sage [2008/10/02(木) 08:53:34 ] PowerPCのアセンブラって、Z80から入った俺にしてみたら すっごくわかりやすかったんだよなぁ 信者になる気持ちもわかる
558 名前:デフォルトの名無しさん [2008/11/15(土) 22:15:50 ] SSE組み込み関数のラッパーを作ったんで 簡単なベンチとったら↓以下のようになった。 SIMDに有利な内容だったとはいえ、SSEは結構すごいんだな floating_point time = 0.012824 std::valarray time = 0.137409 packed_value time = 0.000011
559 名前:デフォルトの名無しさん mailto:sage [2008/11/15(土) 22:50:49 ] あまりに差が大きいんで、 ベンチを見直したら↓になった そりゃそうだよね orz float time = 0.036192 std::valarray time = 0.117789 packed_value time = 0.026709
560 名前:デフォルトの名無しさん mailto:sage [2008/12/02(火) 00:46:09 ] _mm_movemask_epi8に 0x00000000000000FF0000000000000000 渡すとなぜ0x8000になるのですか?
561 名前:デフォルトの名無しさん mailto:sage [2008/12/02(火) 11:54:51 ] >>560 ならないはず。 __m128iにそのデータをセットして_mm_movemask_epi8を 呼び出すまでのコードをアップしてみて。
562 名前:デフォルトの名無しさん mailto:sage [2008/12/02(火) 20:45:48 ] >>561 えーと上のコードだと以下の計算で会ってますか? (0x00 >> 7) << 15 | (0x00 >> 7) << 14 | (0x00 >> 7) << 13 | (0x00 >> 7) << 12 | (0x00 >> 7) << 11 | (0x00 >> 7) << 10 | (0x00 >> 7) << 9 | (0xFF >> 7) << 8 | (0x00 >> 7) << 7 | (0x00 >> 7) << 6 | (0x00 >> 7) << 5 | (0x00 >> 7) << 4 | (0x00 >> 7) << 3 | (0x00 >> 7) << 2 | (0x00 >> 7) << 1 | (0x00 >> 7)
563 名前:デフォルトの名無しさん mailto:sage [2008/12/03(水) 01:27:00 ] >>562 それで0x0100
564 名前:デフォルトの名無しさん mailto:sage [2008/12/03(水) 22:41:53 ] 0x0100 なんで0x0100するの?どこにもそんなこと出てないけど
565 名前:,,・´∀`・,,)っ-○◎● mailto:sage [2008/12/05(金) 08:04:19 ] たぶんさ、 デバッグウィンドウに出てきた16進ダンプをビッグエンディアンだと思い込んでるんじゃないの? 00 00 00 00 00 00 00 FF 00 00 00 00 00 00 00 00 を0x00000000000000FF0000000000000000だと勘違いし 80 00 を0x0080じゃなくて0x8000だと勘違いしてると。
566 名前:デフォルトの名無しさん mailto:sage [2008/12/06(土) 10:02:32 ] そうだったりした 許してください