[表示 : 全て 最新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]
どうぞ

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もマルチコアとマルチスレッド未対応だろ






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

前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