SSE AVXのプログラミング

このエントリーをはてなブックマークに追加
1デフォルトの名無しさん
どうじょ

前スレ
MMX SSE 3D NOW!のプログラミング
http://pc12.2ch.net/test/read.cgi/tech/1085749218/
2デフォルトの名無しさん:2010/05/26(水) 17:33:42
MMXはぶってんじゃねーよ
3デフォルトの名無しさん:2010/05/26(水) 21:26:22
3D NOW!はぶって


よし
4デフォルトの名無しさん:2010/05/27(木) 16:54:37
即死しないといいね。
5:2010/05/28(金) 01:09:31
なんか書きこめよ、
61:2010/05/28(金) 02:52:41
おい、さっさと俺様に役に立つこと書き込めよ
71:2010/05/28(金) 17:06:51
早く書けよ
バカ
8デフォルトの名無しさん:2010/05/28(金) 17:27:54
>>7
即死しなくなるのは 20 くらいだっけ?
君の心意気は買うが、即死しなくなるまで一日一度でよい。
91:2010/05/28(金) 17:36:26
>>8
うぜーよてめぇよぉ
誰にけんかうってんだ?
てゆーかさぁ同一人物の書き込みじゃないんだけど?

んなことより、さっさと何か俺の役に立つことを書き込みやがれ
101:2010/05/28(金) 18:15:51
>>9
うるせ〜よバ〜カ
11デフォルトの名無しさん:2010/05/28(金) 22:24:24
即死を避けたいのはわかるが、罵倒はさすがにいかがなものか。
それっぽいコードを貼る、といった程度で勘弁してもらいたい。
12デフォルトの名無しさん:2010/05/29(土) 13:47:05
>>9
それはいいんだが、翌日になってから投稿すると、効率よく即死回避できるし、
もしかすると無駄な即死回避投稿する前に誰か何かネタを振ってくれるかも知れない。
だから投稿する前に一日待て。
13デフォルトの名無しさん:2010/05/30(日) 01:30:49
AVX使ってみた奴いる?
ど〜だった?使いやすい?
14デフォルトの名無しさん:2010/06/01(火) 01:18:41
何故?
151:2010/06/05(土) 00:13:34
なんか書きこめよ、くずども
16デフォルトの名無しさん:2010/06/05(土) 01:00:22
なんか
17デフォルトの名無しさん:2010/06/05(土) 21:13:26
>>15
無理だろ
たかが1000レスに6年もかかったんだし
2日に1レスが妥当
18デフォルトの名無しさん:2010/06/05(土) 21:16:09
とりあえず前スレのMMX、SSE2、AMD64比較ベンチのソース
ttp://kawahenteko.hp.infoseek.co.jp/myapp.html
19デフォルトの名無しさん:2010/06/12(土) 20:22:54
すすまねえな
20デフォルトの名無しさん:2010/06/15(火) 03:02:12
インテル(R) Advanced Vector Extensions プログラミング・リファレンス
http://download.intel.com/jp/software/AVE/319433-006JA.pdf
p.86
3.2 YMM ステート管理
> AVX とFMA拡張をサポートするには、OS がYMM ステートを管理する必要がある。
> そうでない場合には、AVXあるいはFMA 拡張命令(VEX エンコーディングによる
> 拡張128 ビットSIMD 命令を含めて)を実行すると#UD 例外が発生する。

原文
Intel(R) Advanced Vector Extensions Programming Reference
http://software.intel.com/file/21558
P.90
3.2 YMM STATE MANAGEMENT
> An OS must enable its YMM state management to support AVX and FMA extensions.
> Otherwise, an attempt to execute an instruction in AVX or FMA extensions(including
> an enhanced 128-bit SIMD instructions using VEX encoding) will cause a #UD exception.
21デフォルトの名無しさん:2010/06/15(火) 22:19:14
http://msdn.microsoft.com/en-us/library/ff545910.aspx
In Windows 7 and Windows Server 2008 R2, both 32-bit and 64-bit versions of the operating system preserve the AVX registers across thread (and process) switches.
22デフォルトの名無しさん:2010/06/26(土) 18:26:07
SSEっていつまでサポートされる?
今後SSEのクロックあたりの実行速度が改善される見込みは?
23デフォルトの名無しさん:2010/06/26(土) 23:02:16
> SSEっていつまでサポートされる?
x86/AMD64がサポートされなくなるまで

>今後SSEのクロックあたりの実行速度が改善される見込みは?
複数のμOPに分解して実行していた命令が、1μOPで実行
できるような改良はありえる
24デフォルトの名無しさん:2010/07/01(木) 22:07:45
ビット論理演算て型によらず結果は一緒だよな?
なんで型ごとにあるんだ?
pxor / xorps / xorps とか。
例外も (対応CPUなら) 同じみたいだし。
25デフォルトの名無しさん:2010/07/01(木) 22:14:53
>>24
もすこしSIMDを勉強したほうがよく寝?
26デフォルトの名無しさん:2010/07/01(木) 22:18:17
>>25
どうしてもわからなくて夜も眠れないから
わかるなら教えてくれ!
27デフォルトの名無しさん:2010/07/01(木) 22:22:37
結果の出し方が違くね?
28デフォルトの名無しさん:2010/07/01(木) 22:28:39
結果の出し方は同じじゃね?
29デフォルトの名無しさん:2010/07/02(金) 02:18:02
整数SIMDブロックとFP-SIMDのブロックのそれぞれに用意されている
演算ユニットを明示的に使うため
30デフォルトの名無しさん:2010/07/02(金) 08:31:38
>>29
何のために?省電力?

パフォーマンスを考えた場合、
xorpd, xorps は PORT5 しか使えず、
pxor はPORT0, PORT1, PORT5 の3つを使える為、
pxor のみで十分だが。
31デフォルトの名無しさん:2010/07/02(金) 11:16:59
パフォーマンスのためだ
異なるブロック間でのデータのやり取りにはペナルティがあるので
各ブロックに演算ユニットが用意されている
32 ◆0uxK91AxII :2010/07/02(金) 13:36:20
>>24
歴史的経緯に因る。

pdの追加は謎だけど。
33|ω・`):2010/07/02(金) 13:36:57
ペナルティがあったのって熱湯だけじゃないの?
34デフォルトの名無しさん:2010/07/02(金) 14:59:50
インテル(R) 64 アーキテクチャーおよびIA-32 アーキテクチャー
最適化リファレンス・マニュアル
http://download.intel.com/jp/developer/jpdoc/248966-017JA.pdf
のp.43,.56を読むんだ
35デフォルトの名無しさん:2010/07/02(金) 15:09:42
>>34
chapterごとにページ振ってあるんだが
何章の何ページだ?
36|ω・`):2010/07/02(金) 16:18:55
へー
ポート間じゃなくてintとfpの間に入るんだ
37デフォルトの名無しさん:2010/07/02(金) 22:35:56
addpd xmm0, xmm1
xorpd xmm0, xmm1
addpd xmm0, xmm1
xorpd xmm0, xmm1
....


addpd xmm0, xmm1
pxor xmm0, xmm1
addpd xmm0, xmm1
pxor xmm0, xmm1
....
でパフォーマンスを比べてみた。

●実測
Core2Duo の E8400とT7300では同じタイム。
Corei7 では後者が倍時間がかかった。

●シミュレーション
nehalem / sandy とも同タイム。
38デフォルトの名無しさん:2010/07/02(金) 22:41:17
addpd xmm0, xmm1
mulpd xmm2, xmm3
pxor xmm4, xmm5
pxor xmm6, xmm7
pxor xmm8, xmm9
の繰り返し

のように直後に値を使わない場合は
Corei7 だと pxor の方が実測、シミュレーションとも速い。
Core2Duoはこの場合もまったく同じ。
39デフォルトの名無しさん:2010/07/03(土) 12:28:47
整数演算主体のプロジェクトを
/arch:AVXでビルドしてもあまり速くならないの?
40デフォルトの名無しさん:2010/07/03(土) 12:39:25
SSEとAVX-128bitの組み込み関数は共通なので
コンパイラオプションで生成するバイナリを切り替えられる

整数SIMDの組み込み関数を使っているのなら
多少の性能向上はあると思われる
4139:2010/07/03(土) 12:45:39
>>40
とんくす
42デフォルトの名無しさん:2010/07/03(土) 12:49:48
エスパーだな。
俺はSSEを使っていないコードかと思った。

それだったら、多分最初の実装だとデコーダをカリカリにチューンはしないだろうから
命令の帯域がクリティカルな人は効果あるんじゃない?としか言えない。
命令長が短くなるのと、三項演算のおかげで退避に使う命令を減らせるからコードが全体的に少しだけ小さくなる。
4339:2010/07/03(土) 13:50:08
プロジェクトのほんのごく一部にSSE2のintrinsicを使ってます。
さらに/arch:SSEではほとんど速くならず、
/arch:SSE2ではかなり高速化したプロジェクトです。
44デフォルトの名無しさん:2010/07/03(土) 14:07:09
整数演算入ったのSSE2だし
45デフォルトの名無しさん:2010/07/03(土) 14:26:15
VCの/archはFPのスカラーコードで使う命令セットを
指定するのが主な使い方なので性能向上に過度な期待は
しないほうがいい
4639:2010/07/03(土) 15:01:42
分かりました。どうもありがとうございました。
47|ω・`):2010/07/03(土) 15:24:13
>>37-38
スループットの方は単純に fp logic の実行ポート数じゃん (Core2 は3つ、i7 は1つ)

レイテンシの方は、Core2 の fp logic 命令って実は int スタックらしいよ
だからどっち使っても同じ
48デフォルトの名無しさん:2010/07/04(日) 02:31:05
nehalemでは >>37 は前者の方が速いので、
ペナルティがあると考えるのが妥当かと。

ただ、シミュレーションの結果と一致しないのは気になるが。
49デフォルトの名無しさん:2010/07/04(日) 03:18:18
比較対象が違ってるんだが
50デフォルトの名無しさん:2010/07/04(日) 08:08:34
なにが?
51|ω・`):2010/07/04(日) 10:39:45
Nehalem の fp logic は fp スタックだから
他の fp 命令と繋ぐのはペナルティなし、int<->fp 繋ぐのは2クロックペナルティ
ってことで>>34の資料と一致してるんじゃない

シミュレータは多分うんこ
52デフォルトの名無しさん:2010/07/04(日) 10:50:49
"シュミレーター" の検索結果
約 334,000 件 (0.14 秒)
53デフォルトの名無しさん:2010/07/04(日) 15:06:07
>>51
Nehalem のFP/SIMD/SSE2 Move and Logic の Domain は FP と書いてあるんだけど、
これって嘘なの?
54デフォルトの名無しさん:2010/07/17(土) 20:37:01
__m128(fp32x4)の任意の要素に任意の値を書き込みたいんだが、
どういう実装がベストなのかな?↓がベストかな?

__m128 set_elem( __m128& v, const uint32_t index, float32_t e )
{
ALIGN(16) const float32_t mask_table[4*4] =
{
1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1
};

const __m128 mask = _mm_load_ps( mask_table + index * 4 );
return _mm_or_ps( _mm_and_ps( _mm_set1_ps(e), mask ), _mm_andnot_ps( v, mask ) );
}
55デフォルトの名無しさん:2010/07/17(土) 22:27:13
>>54
言語が何か分かんないけど、
float32_t の 1 でマスク作れるの?
andnot って1個目の引数のnotを取ると思うんだけど、順番あってる?

メモリ経由で、直接変更する要素に e を書くのとどっちが早いかなあ。
56デフォルトの名無しさん:2010/07/17(土) 22:47:40
>>55
すいません、どっちも間違ってましたw
まあ、実際1要素だけ書き換えなんて
やらないんでしょうねえ。
57デフォルトの名無しさん:2010/07/17(土) 22:59:05
4レジスタくらいなら直接保持したほうが速いと思う
で、値は1レジスタにまとめて読み込んで積をとる
58デフォルトの名無しさん:2010/07/24(土) 10:21:46
画像フォーマットの(en|de)codingで効果を発揮するのはSSE2までだけで十分だったりするの?
SSE3 SSSE3 SSE4まで使って頑張ってもSSE2までしか使わない場合と大して変わらないとかあるの?
59デフォルトの名無しさん:2010/07/24(土) 10:45:57
>>58
だんごさんはSSSE3が画像処理に意外と便利だと言っていたけど
60デフォルトの名無しさん:2010/07/24(土) 11:56:53
SSSE3 SSE4.1 SSE4.2は無用の長物。
61デフォルトの名無しさん:2010/07/24(土) 19:55:02
劇的に速くなることはマレだと思うが、
あれば便利な命令は結構ある。
互換性を考えると使いにくいけどね。

一般向け商用ソフトでパフォーマンスが重要なものの場合、
SSE2/SSE3/SSSE3/SSE4.1/SSE4.2/AVX/FMA....
と、すごい種類の可能性があって、
これらすべて用の関数を設計、チューニング、評価なんてとても出来ないから、
SSSE3/SSE4.1/SSE4.2 なんかは飛ばされがち。
62デフォルトの名無しさん:2010/07/24(土) 20:00:27
OOPのインターフェースつかってSSEのXXを対応したバージョンと、
それ以外のコードの2種類くらいを用意してあげればいいんじゃね?

環境はユーザー責任でスイッチしてもらう。
63デフォルトの名無しさん:2010/07/24(土) 22:04:16
>>62

それやりたいんだけどさ、C++のメンバ関数をアセンブラでどう書けばいいのかがわからない。
インラインアセンブラで書いたプログラムを64ビット用にコンパイルしようとしたら
cl64.exeはインラインアセンブラには対応してないとかエラーが出てコンパイルできないorz
64デフォルトの名無しさん:2010/07/24(土) 22:23:50
>>63
cl64.exeはインラインアセンブラ非対応。
ml64.exeを使うかintrinsic命令を使うかしかない。

>>62
ユーザーが自分でスイッチは無いな。
普通は実行時に自動判別。

事情により新命令を使ったバージョンしか作らないのなら、
対応してないCPUでの実行時は非対応CPUである旨を表示する。

個人で作った個人用アプリなど、非常に限られた人しか使わないのであれば、
非対応CPUで使ったらいさぎよくOSの例外発生メッセージが出るのもありかも。
65デフォルトの名無しさん:2010/07/25(日) 00:01:02
>>63
ぶっちゃけそのプログラムは64ビットネイティブにする必要はあるのか?
66デフォルトの名無しさん:2010/07/25(日) 09:11:31
>>65
おれは最近は、個人でしか使わない趣味のプログラムはすべて64bitネイティブだよ。
レジスタが倍あるし、いまさら窮屈なレジスタ数で組みたくない。
C++オンリーでもパフォーマンスは上だし。
67デフォルトの名無しさん:2010/07/25(日) 15:07:56
制約が緩くなるのはどう考えても悪いことじゃないな
68デフォルトの名無しさん:2010/07/25(日) 15:17:40
>>66そのきもちはすこしわかる。

68系のデータ8本、アドレス8本の環境から、
86系に移ってきたときには窮屈な思いをしたもんだ。
69デフォルトの名無しさん:2010/07/25(日) 19:10:36
>>65
>>63だが、>>66が全部言ってくれた。
インラインアセンブラで組んだウェーブレット変換のプログラムを
ちょっと64ビットで動かしてみたくなったのさ。
70デフォルトの名無しさん:2010/07/25(日) 21:32:13
CL /FA でアセンブリ出力して、修正、アセンブル、リンクですかのう。
7163:2010/07/26(月) 00:58:40
>>69
ありがとう
/FAオプションつけてコンパイルしたら、.asmファイルが出てきた
やる気出てきた。

ただ、今はDirectCompute用のプログラム書いてるんだけどね...
一応strategyパターン使ってCPU用とGPU用の処理を分けてる。
72デフォルトの名無しさん:2010/08/08(日) 13:17:01
自作のSSEラップクラスとXMMATRIXの行列積について
生成されるコードを見比べてみたところ(VC2010EE)
自作のは並べ替えが甘くメモリ退避が多く、そのせいか命令数が倍ぐらいで
XMMATRIXのに比べて1.5倍ぐらい遅かった。

違いといえばXMMATRIXはイントリンシック命令直書きで
自作のは薄いクラスでラップされているぐらい。畳み込みで
同等のコードが生成されるはずなのに・・

結局、イントリンシック命令は直書きしないと
最適化がオミットされちゃうんですかね?
73デフォルトの名無しさん:2010/08/08(日) 18:33:50
>>72
ラップすればするほどパフォーマンスが落ちるのは当たり前だ。
さらに作者の能力や熱意にも大きく依存する。
74デフォルトの名無しさん:2010/08/09(月) 11:33:36
>>72
メモリのアクセスパターンは重要だよ。命令数が同じでも、キャッシュに乗ってないメモリアクセスが入ると途端に遅くなる。
75デフォルトの名無しさん:2010/08/09(月) 22:13:49
>>73
適当なことを言うなよ。

>ラップすればするほどパフォーマンスが落ちるのは当たり前だ。
なぜ当たり前と言えるんだ?
別にいくらラップしようが__forceinlineをつけて展開すれば
最後に出来上がるものは同じじゃねーか。
事実、全てインライン展開されているのは確認しているし、
そっから先最適化するかしないかは、コンパイラがやるかやらないかでしかない。
結局、コンパイラが何か俺のわからない理由で最適化を打ち切っているようにしか
みえない。

>さらに作者の能力や熱意にも大きく依存する。
同等のコードが生成されるはず、と書いているように
そもそも同じ様式を採用している。

>>73
一応、ベンチマークなんで、同じ条件で回している。

76デフォルトの名無しさん:2010/08/09(月) 22:22:23
>>75
じゃあ勝手に好きなようにやれ
77デフォルトの名無しさん:2010/08/09(月) 22:45:31
>>76
結局ちゃちゃいれて終わりか。
なんつーか、無意味な奴。
78デフォルトの名無しさん:2010/08/09(月) 22:50:48
>>75
確かに、よく分からない理由で
コンパイラが最適化の手をゆるめる事はある

PGOを適用すればレジスタをよりうまく使い回して
メモリアクセスが減るけど
Expressじゃ使えないんだよね
79デフォルトの名無しさん:2010/08/10(火) 08:26:58
コンパイラの最適化を過信しすぎだな。
80 ◆0uxK91AxII :2010/08/10(火) 10:45:56
81デフォルトの名無しさん:2010/08/10(火) 11:17:27
>自作のは並べ替えが甘くメモリ退避が多く
>一応、ベンチマークなんで、同じ条件で回している

自己矛盾にも気付けないらしい。
82デフォルトの名無しさん:2010/08/10(火) 22:05:00
>>81
お前バカだろ、もう出てくるなよ。
つーか、何か言いたいことがあるなら
自分が試した結果を交えて話せ。
糞の役にも立たないんだよ。
83デフォルトの名無しさん:2010/08/11(水) 10:26:26
>>82
悪いけど、コンパイラによる話なんだから該当コンパイラのスレでやってくれ。
空気悪くなって迷惑。

それと、具体的なコードを出さない限り具体的な話なんてできないよ。
84デフォルトの名無しさん:2010/08/11(水) 18:41:23
SSEと番人は相性悪いな
結局ループせず必要な回数だけ命令を並べるほうが速い
以上チラ裏でした
85デフォルトの名無しさん:2010/08/11(水) 18:48:22
>>81
自作:メモリ退避が多い
自作じゃない方:メモリ退避が多くないらしい

どう見ても自作の方が不利ですね。ご指摘本当にありがとうございました。
86デフォルトの名無しさん:2010/09/08(水) 18:39:35
進まないね
もう他のCPUのSIMDの話題もおkにしない?
87デフォルトの名無しさん:2010/09/09(木) 11:25:36
他のCPUってARMのNEONとかか?
88デフォルトの名無しさん:2010/09/16(木) 20:42:14
SSEのプリフェッチ命令を使っても効果が出ない。
使い方がわからないんだよな。
89デフォルトの名無しさん:2010/09/16(木) 20:54:23
距離を測ってそれに合わせたタイミングで発行すればよろし
90デフォルトの名無しさん:2010/09/16(木) 21:03:34
CPU固有の最適化になるわさ
そらICCも_mm_prefetchを消したくなるわ
91デフォルトの名無しさん:2010/09/16(木) 22:07:39
キャッシュが潤沢で
ハードウェアプリフェッチが効いてる環境だと
ソフトウェアプリフェッチは要らないんじゃないの?
92デフォルトの名無しさん:2010/09/17(金) 09:07:54
Core2,、Core iのハードウェアプリフェッチの動作仕様を書いた
文書はあるのか?
93デフォルトの名無しさん:2010/09/17(金) 13:27:24
1.ループの外でバッファの先頭を指定して_mm_prefetch_ntaする。
2.ループ内で、バッファ先頭から順に読んで処理し、_mm_stream_si128で書き出す。

このとき、CPUが気をきかせて、1ループにかかった時間から最適な距離を判断して、
キャッシュ汚染しないプリフェッチをハードウェアで自動的にしてくれたりする?
94デフォルトの名無しさん:2010/09/17(金) 13:31:41
表記間違えてるけどそこは無視してお願い
95デフォルトの名無しさん:2010/09/19(日) 13:38:02
for(i=0;i<16;i++)
a[i]^=(d[i]+c[i])%16;
このプログラムをSSE2で書きたいのですがわかりません。
教えてください。よろしくお願いします。
96デフォルトの名無しさん:2010/09/19(日) 14:18:07
宿題か?
97デフォルトの名無しさん:2010/09/19(日) 14:24:07
暗号を作っているんですけど高速化したいんです。メインループは
for(k=0;k<500000;k++){
for(j=0;j<16;j++){
for(i=0;i<32;i++){
d[i]^=GF[mlt(FG[a[j]],FG[h[i][FG[b[j]]]])];
}
}
こんな感じなんですがGPGより4倍くらい遅いです。
98デフォルトの名無しさん:2010/09/19(日) 14:45:45
>>95
全部あんろーる

>>97
コンパイラさんに任せてあきらめる
99デフォルトの名無しさん:2010/09/19(日) 14:49:48
あんろーるってなんですか?
128ビット単位なので必要のないループが減らせたら高速化できると思うので
基本的に行列演算の高速化だと思います。
100デフォルトの名無しさん:2010/09/19(日) 14:58:34
iccでベタ書きして最適化オプション/pragmaを加えるだけでおk?
101デフォルトの名無しさん:2010/09/19(日) 15:01:15
すみません、具体的にコマンドラインを教えてください。
使用環境はCygwin32,gcc4です。
コンパイラに任せてもSSE2命令に変換してくれるのでしょうか?
102デフォルトの名無しさん:2010/09/19(日) 15:03:49
実験したいからとりあえずmltとGF,FGの型おせーて
103デフォルトの名無しさん:2010/09/19(日) 15:06:13
>>101
iccならベタ書きの内積計算関数でdpps使ってくれたりするから多分いやもしかしたらいけるかもしれない
104デフォルトの名無しさん:2010/09/19(日) 15:08:47
int N=256;
static int GF[256];(GF(256)有限体の元)
static int FG[256]; GF(256)の対数値

int mlt(x, y){

if(x==0||y==0)
return 0;

return ((x+y-2)%(N-1))+1;
}
です。よろしくお願いします。
105デフォルトの名無しさん:2010/09/19(日) 15:13:44
int h[32][256];
追加です。因みに

for(i=0;i<16;i++)
a[i]^=(d[i]+c[i])%16;

の高速化だけでもいいです。
106デフォルトの名無しさん:2010/09/19(日) 15:15:24
ループから外して式をばらすってことですか?>あんろーる
107デフォルトの名無しさん:2010/09/19(日) 15:18:04
C言語からインラインアセンブラで呼び出したいと思うのですが、
うまくいきません。
moveq d,%xmm0
moveq c,%xmm1
paddb %xmm1,%xmm0
moveq a,%xmm1
pxor %xmm1,%xmm0
配列のデータをレジスタにセットするところもわかりません。
108デフォルトの名無しさん:2010/09/19(日) 22:03:16

518 :デフォルトの名無しさん:2010/09/19(日) 14:20:02
for(i=0;i<16;i++)
a[i]^=(d[i]+c[i])%16;
このプログラムをSSE2で書きたいのですがわかりません。
教えてください。よろしくお願いします。
C言語からインラインアセンブラで呼び出したいと思うのですが、
うまくいきません。
moveq d,%xmm0
moveq c,%xmm1
paddb %xmm1,%xmm0
moveq a,%xmm1
pxor %xmm1,%xmm0
配列のデータをレジスタにセットするところもわかりません。
109デフォルトの名無しさん:2010/09/20(月) 20:17:26
>>107
インラインアセンブラ嫌いだから組み込み関数で書くけどこんな感じ。
_mm_storeu_si128((__m128i*)a,_mm_xor_si128(_mm_loadu_si128((__m128i*)a),_mm_and_si128(
_mm_add_epi8(_mm_loadu_si128((__m128i*)b),_mm_loadu_si128((__m128i*)c)),_mm_set1_epi8(0x0f))));
110デフォルトの名無しさん:2010/09/22(水) 03:27:19
トリックを重ねたSandy Bridgeマイクロアーキテクチャ
http://pc.watch.impress.co.jp/docs/column/kaigai/20100922_395394.html
111デフォルトの名無しさん:2010/09/22(水) 06:24:35
>>110の記事で256ビットを演算器の使い回しで実現するって部分で
128ビット幅の浮動小数点用と128ビット幅の整数演算用を使ったってのがよく理解できなかった

128ビットについては普通に浮動小数点用のを使って、
整数演算用が同サイクルに使われることがないから、
整数の加算乗算シフトとかを組み合わせて浮動小数点と同じことをしてるってことかな?
112デフォルトの名無しさん:2010/09/22(水) 09:17:56
#include <stdio.h>
#include <stdlib.h>

int main(void){
unsigned long long int a,b;

a=strtoull("0x1111111111111111",(char **)NULL,16);
b=strtoull("0x2222222222222222",(char **)NULL,16);
a=a^b;
printf("%llu\n",a);

return 0;
}
このプログラムをMMXを使って最適化したいのですがわかりません。
アセンブラで書くしかないのでしょうか。
113デフォルトの名無しさん:2010/09/22(水) 11:09:59
>>112
マルチうざい。
114デフォルトの名無しさん:2010/09/22(水) 14:08:51
>>110
つまりAVXはSSEより速くはならないってこと?
単精度の4次元ベクトルは扱うことがあっても8次元や倍精度とか使わないからなぁ

これの最速のSSEコードを教えてください
32ビットカラービットマップを24.8固定小数点で線形補間するコードです
自分で書いてはみたものの元のCより遅いので
typedef struct
{
union
{
unsigned char b, g, r, a;
unsigned long c;
};
} COLOR;
unsigned long Get(unsigned x, unsigned y, COLOR* Table, unsigned width, unsigned height)
{
COLOR c;
c.r = (
(Table[(y >> 8) * width + (x >> 8)].r * (0x100 - (x & 0xff)) + Table[(y >> 8) * width + (x >> 8) + 1].r * (x & 0xff)) * (0x100 - (y & 0xff))
(Table[((y >> 8) + 1) * width + (x >> 8)].r * (0x100 - (x & 0xff)) + Table[((y >> 8) + 1) * width + (x >> 8) + 1].r * (x & 0xff)) * (y & 0xff)
+ 0x8000) >> 16;
以下g, b, aと繰り返す
return c.c;
}
115デフォルトの名無しさん:2010/09/22(水) 14:20:15
>>114でCで実際に書いたときは乗算に[257][256]のテーブルを使用してました
116デフォルトの名無しさん:2010/09/22(水) 14:40:16
257だと!?
117デフォルトの名無しさん:2010/09/22(水) 21:10:04
このループはSSE2使っても早くならないですか?
ていうかSSE2使えますか?
for(j=0;j<16;j++){
for(i=0;i<16;i++){
d1[j]^=GF[e1[j][i]];
d2[j]^=GF[e2[j][i]];
}
}
118デフォルトの名無しさん:2010/09/22(水) 21:33:03
xorだけsimd使ってもなぁー
d1の計算とd2の計算で2つスレッド使って別にループ回す方が
それにしてもsynchronizeのコストがあるしなぁ
119デフォルトの名無しさん:2010/09/23(木) 05:41:30
配列の配列ってアドレスがバラバラだからSIMD処理できないかも。
120デフォルトの名無しさん:2010/09/24(金) 02:10:48
SSE使うかどうかに関係無く、参照アドレスが連続なる様にしておかないと
キャッシュミスして処理速度がガタ落ちになる

昔ならともかく、今はどうしても明示的にSSEをしなければならない場合以外は
コンパイラー任せでいいんじゃないの
121デフォルトの名無しさん:2010/09/24(金) 02:11:29
SSEを使用しなければならない場合以外は
122デフォルトの名無しさん:2010/09/30(木) 02:18:33
変数は全部unsigned charですがコンパイラでやるとSSE2命令にしてくれません。
丸投げですが、組み込み関数でもいいのでSSE2のアセンブリコードをお願いします。

for(j=0;j<16;j++){
a[j]^=(d1[j]+c[j])&0xff;
b[j]^=(d2[j]+c[j])&0xff;
buf[j]^=d1[j];
buf[j+16]^=d2[j];
}
123デフォルトの名無しさん:2010/09/30(木) 07:36:26
またお前か
124デフォルトの名無しさん:2010/09/30(木) 07:41:34
128*2でしか使えないのか
蓋を開けてみればAVXも残念なものだった
125デフォルトの名無しさん:2010/09/30(木) 09:31:46
高々数万のCPUに過大な期待すんな。
126デフォルトの名無しさん:2010/09/30(木) 09:46:55
現プロセスにおいてトランジスタ効率上げるための折衷仕様だから、
いずれ改善されるだろう
127デフォルトの名無しさん:2010/09/30(木) 22:14:46
>>124
> 128*2でしか使えないのか
コアあたり、1クロックで256bitレジスタの加減算と積が出来ると思うんだけど。
128デフォルトの名無しさん:2010/10/01(金) 14:51:58
>>122
じゃあ、こんな感じで。
__m128i *pa = (__m128i*)a; __m128i *pb = (__m128i*)b; __m128i *pc = (__m128i*)c;
__m128i *pd1= (__m128i*)d1;__m128i *pd2= (__m128i*)d2;__m128i *pbuf=(__m128i*)buf;
__m128i *pa = (__m128i*)a; __m128i *pb = (__m128i*)b; __m128i *pc = (__m128i*)c;
__m128i *pd1= (__m128i*)d1;__m128i *pd2= (__m128i*)d2;__m128i *pbuf=(__m128i*)buf;
__m128i va, vb, vc, vd1, vd2;
va = _mm_loadu_si128(pa); vb = _mm_loadu_si128(pb); vc = _mm_loadu_si128(pc);
vd1 = _mm_loadu_si128(pd1); vd2 = _mm_loadu_si128(pd2);
_mm_storeu_si128(pa, _mm_xor_si128(va, _mm_adds_epu8(vd1, vc)));
_mm_storeu_si128(pb, _mm_xor_si128(vb, _mm_adds_epu8(vd2, vc)));
_mm_storeu_si128(pbuf++, _mm_xor_si128(_mm_loadu_si128(pbuf), vd1));
_mm_storeu_si128(pbuf, _mm_xor_si128(_mm_loadu_si128(pbuf), vd2));
129デフォルトの名無しさん:2010/10/02(土) 08:25:41
エラーがでるよ。こうやって書いて!

_mm_storeu_si128((__m128i*)a,_mm_xor_si128(_mm_loadu_si128((__m128i*)a),_mm_and_si128( _mm_add_epi8(_mm_loadu_si128((__m128i*)d1),_mm_loadu_si128((__m128i*)c)),_mm_set1_epi8(0x0ff))));
_mm_storeu_si128((__m128i*)b,_mm_xor_si128(_mm_loadu_si128((__m128i*)b),_mm_and_si128( _mm_add_epi8(_mm_loadu_si128((__m128i*)d2),_mm_loadu_si128((__m128i*)c)),_mm_set1_epi8(0x0ff))));
130デフォルトの名無しさん:2010/10/02(土) 08:27:27
あとこれも何とかして

for(j=0;j<16;j++){
for(i=0;i<16;i++){
d1[j]^=GF[e1[j][i]];
d2[j]^=GF[e2[j][i]];
}
}
131デフォルトの名無しさん:2010/10/02(土) 09:40:15
エラーが無くなりました。早とちりでした。
132デフォルトの名無しさん:2010/10/02(土) 10:02:14
buffに代入されません。

memcpy(&buff[32*k],buf,32);
133デフォルトの名無しさん:2010/10/02(土) 10:18:44
134デフォルトの名無しさん:2010/10/02(土) 10:20:44
マルチポストがいけないとは言わないが、アルゴリズムとコードと態度の糞っぷりが果てしない。
135デフォルトの名無しさん:2010/10/02(土) 14:16:41
_mm_storeu_si128(pbuf++, _mm_xor_si128(_mm_loadu_si128(pbuf), vd1));
_mm_storeu_si128(pbuf, _mm_xor_si128(_mm_loadu_si128(pbuf), vd2));

pbuf--;
buf[0]=*pbuf->m128i_u8;
pbuf++;
buf[16]=*pbuf->m128i_u8;
clではコンパイル出来るのに、GCCだと共用体のメンバじゃないというエラー
が出てコンパイルできません。なぜですか。正しい代入方法を教えてください。
136デフォルトの名無しさん:2010/10/02(土) 14:43:21
_mm_storeu_si128(pbuf++, _mm_xor_si128(_mm_loadu_si128(pbuf), vd1));
_mm_storeu_si128(pbuf, _mm_xor_si128(_mm_loadu_si128(pbuf), vd2));

pbuf--;
buf[0]=*pbuf->m128i_i8;
pbuf++;
buf[16]=*pbuf->m128i_i8;

書いてもらったプログラムなのでよくわかりませんが、128ビットの
共用体を2つ分使っているのではないかと思います。
ところで上のプログラムをclでコンパイルすると通るのに、GCCだと
共用体のメンバじゃないといわれてエラーが出ます。pbufからbufに
値を代入する正しい方法を教えてください。もしくはmemcpyでpbuf
からbuffに代入する方法があったら教えてください。よろしくお願いします。
137デフォルトの名無しさん:2010/10/02(土) 14:56:38
memcpyの使い方も知らない人はC言語の勉強からやり直した方が良いと思うんだ。
大体にして、スピードなんて後でいいだろ。
本当に良いプログラムなら指数的なオーダーで遅くならない限りみんな使ってくれるし、そんな良いソフトがオープンソースならガリガリに最適化してくれる人も現れるよ。
138デフォルトの名無しさん:2010/10/02(土) 15:01:50
何かを習得するのって本当に難しい。使いながら解らない所を調べて
いくという感じで。ネットで調べてるんだけどなかなかいい情報が
得られない。エラーメッセージの意味もよくわからないし。
139デフォルトの名無しさん:2010/10/02(土) 15:06:30
何を調べてるのかしらないが、英語の資料を除外してるといい情報は出ないぞ
いい情報は英語でしかないことが多い
140デフォルトの名無しさん:2010/10/02(土) 16:45:14
>>114を教えていただけませんか?
Cより高速化できる見込みがあるかどうかだけでも結構です
141デフォルトの名無しさん:2010/10/03(日) 21:02:01
>>140
ソース見にく過ぎ
142デフォルトの名無しさん:2010/10/05(火) 06:14:52
見込みはないです。
143デフォルトの名無しさん:2010/11/01(月) 01:24:37
AMDを応援したいがAVX対応が1年も遅れるようじゃSandyBridgeを買わざるを得ない。
144デフォルトの名無しさん:2010/11/01(月) 01:31:18
地雷踏みはIntel信者の団子にでも任せておけばいいじゃないか。
145,,・´∀`・,,) ・・・→ -○○○:2010/11/02(火) 19:37:28
SDE使えばAMDのCPUでもAVXのコードを実行できるんだから好きにしろよ
むしろSandy Bridge出てからコード書こうと思ってるならどのみち出遅れてるから
いっそBulldozerまで待ってやれよ

146デフォルトの名無しさん:2010/11/05(金) 19:55:53
>>145
シミュレーションじゃ実行速度のメリットをまったく味わえないじゃないか。
俺は既にXOP向けのコード書いてるから実機(Bulldozer)は少なくとも買うよ。

BulldozerってSIMDユニットは結局1モジュールあたり4基(MMX×2、FMAC×2)だよな?
FPではクロック当たり性能で差は付かなさそうだ。
あとは整数だが、FMAC側でも簡単な整数論理演算ができれば胸熱なんだが。

FP積和算の理論スループットは同クロックならSandy Bridge 4コア=Bulldozer 8コアで
あとは整数
148デフォルトの名無しさん:2010/11/06(土) 02:28:59
>>147
俺は素直に先に出るSandyを買うよ。
その先はAMDのFMA4とintelのFMAの動向が見えてきたら考える。
命令セットだけ見るとFMA4の方が良いが....
どっちも買えばいいじゃん。

Intel現行仕様の3オペランドFMAはAMDも「Bulldozer 2」で対応するらしい。
いっぽうIntelの4オペランドFMAの採用計画は不明。もともとIntelの提案仕様だしVEX空間にあるので
採用しない理由はないと思うが。

実際プログラム書いてみたけど3オペランドで困るケースって本当に.少ないんだわ。
しかもほとんどのケースでvfmadd231psで事足りる(132, 213は殆ど使わない)
むしろ3オペランド版のほうが1バイト短い。
どうせなら4オペランド版はimm8の残り4ビットを何かのオプションとして使いたいよね。
vbroadcastss + fmaddpsを1命令に纏めることができるとかさ。


Intelが3オペランド仕様に修正した技術的な理由はなんとなくわかる。
iaca使ってみればわかるが、AVXで4オペランド命令は複合命令ばっかしだぜ。
Simpleデコーダのロジックケチりたいんだろ。
150デフォルトの名無しさん:2010/11/06(土) 08:22:34
>>149
AMDがintel仕様の3オペランドのFMAに対応するってマジか?
ソースきぼんぬ。
> These patches add support for upcoming bdver2 AMD processors:
> BMI (Bit Manipulation Instructions)
> TBM (Trailing Bit Manipulation)
> FMA3 (three operand FMA) instructions
>
> The public specifications for BMI and TBM are in progress (they are
> today available under NDA). They will appear in one of the AMD64
> Architecture Programmer's Manual Volumes 3-6. I can post the
> mnemonics definitions if needed. The FMA3 specification is documented
> in http://software.intel.com/en-us/avx/

http://archives.free.net.ph/message/20101015.184549.56493850.ja.html

bdver2ってのが22nm版なのか後期リビジョンなのかが不明
152デフォルトの名無しさん:2010/11/06(土) 16:58:50
>>151
thx
FMAの命令セットの分裂は避けられたってことか。
こうでそ

AMD「SSE5で3オペランドFMAをサポートします」

Intel「うちもそっくりそのまま+addsub命令も加えて4オペランドFMAをサポートします」

AMD「SSE5やめてAVX互換で仕切りなおします。FMAはIntelさんと同じ4オペランド方式になります」
Intel「デコードコストが大きいのでやっぱ4オペランド当分やめて3オペランド(新方式)でやります」

AMD「え?」
Intel「え?」


てか、SSE5にあったCVT16はXOP→VEX(Intelもサポート)という流れになってるし
IntelとてAMDはAVX普及に協力してもらう立場。
摺り寄せは当然やるでしょう
154デフォルトの名無しさん:2010/11/06(土) 19:53:42
intelが元々考えてた4オペランドと
AMDが一番初めに考えてた3オペランドの
命令の詳細を見たことが無いけど、

これって
今の AMD FMA4 / intel FMA と同じ?
・AMDのSSE5版FMA・・・廃止
・AMDのFMA4(現行)・・・Intelの初期仕様のFMAそのもの
・IntelのFMA・・・4オペランド→3オペランド(まったくの新規)

SSE5仕様書のミラーがあったwww
ttp://www.cs.northwestern.edu/~pdinda/icsclass/doc/AMD_ARCH_MANUALS/

Intel AVX規格書第3版(FMA仕様改定前)
ttp://softwarecommunity.intel.com/isn/downloads/intelavx/Intel-AVX-Programming-Reference-319433003.pdf
156デフォルトの名無しさん:2010/11/06(土) 20:13:54
>>155
オー、
thx、very much!
157デフォルトの名無しさん:2010/11/07(日) 19:06:08
デスクトップのBulldozerは4月以降か、思ったより速いよ。
ESが12月で4月に生産とか本当に出来るのかあやしい
159デフォルトの名無しさん:2010/11/07(日) 19:39:10
ベンチマダー?
160デフォルトの名無しさん:2010/11/08(月) 00:59:39
> デスクトップのBulldozerは4月以降か、思ったより速いよ。
早いが速くない
161デフォルトの名無しさん:2010/11/10(水) 18:00:17
>>147
斜め下の期待を裏切らないAMDの事だから
直近: Sandy Bridge 4コア vs Bulldozer 4or6コア(2or3モジュール)
将来: Sandy Bridge 6コア vs Bulldozer 8コア(4モジュール)
とかってなりそうな気がしてる。そうするとFPで負けそう。
162デフォルトの名無しさん:2010/11/15(月) 08:27:26
将来512bitとか1024bitのレジスタ作ったとき
VEXプリフィックスでどうやって指定するのかね?
Lは1bitしか用意されてないし
全然別系統の命令ということにするのかね?
163デフォルトの名無しさん:2010/11/15(月) 08:57:09
3ビット余ってるって言ってたところ(3バイトVEXの第2バイト)使うんでしょ
長さ指定があっちゃこっちゃ散らばって、汚いなさすがイッテルきたない
164デフォルトの名無しさん:2010/11/15(月) 11:03:35
無料RPG製作ツール「ロープレジェネレーター」
http://sekisekki.net/index.htm

特徴
直感的操作で簡単なゲームが作れます。
簡単に配布可能な状態に出力することができます。
HSP(ttp://hsp.tv/)製のソースコード付きで、スクリプトの知識があれば
自由度の非常に高いカスタマイズができます

・要望、不満点、バグ報告、応援メッセージなどなど書き込みお願いします。
今もどんどん進化中だ。
165デフォルトの名無しさん:2010/11/20(土) 16:53:10
FPUとSSEを交互に使うと待機時間が減って高速化できるとどこかで見たことがあるんだが
FPUとAVXを混ぜると速くなるとかってあるのか?
Pen4からSSEのユニットでFPUをシミュレートしてるらしいし現状のAVXはSSEを2個並べてシミュレートしてるらしいから無理なのかな?
>>165
Pentium IIIのときはx87ユニットとSSEユニットが分かれてて論理レジスタも別だから
並列動作させることができてそういうことも起こりえた。
今となってはx87全面禁止にしたほうがいい。
167デフォルトの名無しさん:2010/11/20(土) 18:12:02
128bit浮動小数が普及するのはいつになるのだろう
168デフォルトの名無しさん:2010/11/20(土) 19:03:34
>>166
x87から切り捨てるならもっと古いx86は使わずAMD64やIA64を使えという話になってしまう。
互換性より速度が重要ならそれでいいかもしれんが。
別にx87が動かないわけじゃない。速くないだけ。
170デフォルトの名無しさん:2010/11/20(土) 20:53:11
>>167
128bit, 256bit, 多倍長, などのライブラリを自作してるオレからしてみると
早く普及してほしい。
ついでに、128bit 整数も欲しい。

が、用途が限られすぎて普及しないと思う。
171デフォルトの名無しさん:2010/11/20(土) 21:10:09
>>170
俺もライブラリ作っているんだけれど、範囲被ってたりしないかなあ。
それはオープンソース?
172デフォルトの名無しさん:2010/11/20(土) 22:22:18
今の所FORTRANのREAL*4ぐらいか?128ビット浮動小数点の利用価値が高いのは

C/C++でもlong doubleが128ビット長になる(規格には入らないだろうが)可能性はあるな
173デフォルトの名無しさん:2010/11/20(土) 22:43:43
REAL*4でなくてREAL*16だろ
どちらにしろ標準FORTRANの文法から逸脱しているのでコンパイラの独自拡張になるが
174デフォルトの名無しさん:2010/11/21(日) 05:05:28
>>171
公開してない自分用。
趣味の数値計算、組み合わせ計算、確率計算で使用。
ライブラリと言ってもlibやdllじゃなくて基本はソースのまま(cppとasm)。
asm部分は最近は64bit用しかメンテしてない。

一通りの関数は作ってあるつもり。
多倍長の乗算はフーリエ変換、
除算、ルートと一部の無理関数はニュートン法、
円周率はガウスルジャンドル、
他の無理関数はテーラー展開。
175デフォルトの名無しさん:2010/12/03(金) 14:05:33
1100|0100 RXBm|mmmm||Wvvv|vLpp
1100|0101 Rvvv|vLpp

VEXと16進数の変換に一瞬頭が混乱する
もう歳だな・・・
176デフォルトの名無しさん:2010/12/03(金) 16:17:13
64bitだとdoubleのシフト・回転も一発で出来て楽だな
177デフォルトの名無しさん:2010/12/03(金) 20:03:41
Intel FMAの231, 213, 132ってのを似非4オペランド形式で記述できるYASM用マクロ書いてみたけど
こういうの需要ある?
178デフォルトの名無しさん:2010/12/03(金) 20:09:32
そーいうのはいちいち他人にお伺い立てるんじゃなくて、
自分が公開したいしたくないで決めるもんだ
179デフォルトの名無しさん:2010/12/16(木) 07:43:12
SSEとあんまり関係ないかもしれないけど、
普通のCPUの浮動小数点演算回路って
倍精度と単精度が別々にあるの?
それとも倍精度の一部を使って単精度にしてるかそれか単精度2つで倍精度作ってるのか、
それとも倍精度はかけるクロック数が違うだけで回路は共通なのか

どうなんでしょうか
180デフォルトの名無しさん:2010/12/16(木) 07:58:41
SSEみたいなものを除けば、単精度演算回路自体を省略している方が多いんじゃないかと。
181デフォルトの名無しさん:2010/12/19(日) 07:45:58
SSE/SSE2で全ビット1にするにはどうしたらいいの?
論理否定命令とか見当たらないんだが・・
182デフォルトの名無しさん:2010/12/19(日) 08:03:08
>>2
IntelはもうMMX使うの止めてくれ、って言ってなかった?
183181:2010/12/19(日) 08:17:33
_mm_cmpeq_pdでいいみたい
184デフォルトの名無しさん:2010/12/19(日) 12:04:51
>>181,183
_mm_cmpeq_ps, _mm_cmpeq_pdだとNaNの時に1にならないから、z=_mm_setzero_pd();m=_mm_cmpeq_pd(z,z)
ってするか、_mm_cmpeq_epi32を使う。
あともっと手っ取り早いのは_mm_set1_epi32(0xFFFFFFFF)とする。
よく使われるならL1に入っているはずだからこれが一番速い。ミスヒットすると一番遅いけどね。
185デフォルトの名無しさん:2010/12/19(日) 14:31:32
>>184 ベンチとってみた

// case 1
f0 = _mm_setzero_ps();
for( uint_t i = 0; i < UINT_MAX; ++i )
{
const __m128 f1 = _mm_cmpeq_ps( _mm_setzero_ps(), _mm_setzero_ps() );
f0 = _mm_add_ps( f0, f1 );
}

// case 2
f0 = _mm_setzero_ps();
const __m128 f1 = _mm_setzero_ps();
for( uint_t i = 0; i < UINT_MAX; ++i )
{
const __m128 f2 = _mm_cmpeq_ps( f1, f1 );
f0 = _mm_add_ps( f0, f2 );
}

// case 3
f0 = _mm_setzero_ps();
for( uint_t i = 0; i < UINT_MAX; ++i )
{
__m128i i1;
const __m128i i2 = _mm_cmpeq_epi32( i1, i1 );
f0 = _mm_add_ps( f0, _mm_castsi128_ps(i2) );
}
186デフォルトの名無しさん:2010/12/19(日) 14:32:48
// case 4
f0 = _mm_setzero_ps();
for( uint_t i = 0; i < UINT_MAX; ++i)
{
const __m128i i1 = _mm_set1_epi32( 0xffffffff );
f0 = _mm_add_ps( f0, _mm_castsi128_ps(i1) );
}

// 結果
case 1: time = 6.090190
case 2: time = 4.637256
case 3: time = 4.636985
case 4: time = 4.620227

case3が良さそう。
つーか、case1よりcase2の方が速いのが解せない。
_mm_setzero_ps()って、何か効率の悪い方法で0生成してるの?
アセンブラ見てみろよ。case1はたぶんこうなってるから。

xorps xmm0, xmm0
xorps xmm1, xmm1
cmpeqps xmm0, xmm1

命令数が増えてデコーダネックってところだろう。
いくら同一レジスタ間のxorが実行ポートを使わないだのレジスタリネーミングのヒントになるだの言っても
デコーダは通るわけだからな
188デフォルトの名無しさん:2010/12/19(日) 15:35:05
Case1は、_mm_setzero_ps()の呼び出しがループの外に出されている以外は
大体そのままの形でした。

Case2は、「const __m128 f2 = _mm_cmpeq_ps( f1, f1);」自体
ループの外に出されちゃってました。

つまりベンチが失敗してました、すんまそん(T_T)
189デフォルトの名無しさん:2010/12/20(月) 05:18:48
そういやこのスレ立てたのは俺だった
細菌CUDAに凝ってSSE使うケース減ったな
190デフォルトの名無しさん:2010/12/20(月) 11:13:45
細菌CUDA……バイオテロみたいだ
191デフォルトの名無しさん:2010/12/20(月) 17:06:14
CUDA速いの?
192デフォルトの名無しさん:2010/12/20(月) 17:15:48
使い方による
間違えれば効果なし
使えるアプリ使えないアプリの見極めが必要
はっきり言って使いこなしはかなり難しい
193デフォルトの名無しさん:2010/12/20(月) 17:25:23
Cellより使いづらそうに見えるんだが気のせいだろうか?
194デフォルトの名無しさん:2010/12/20(月) 17:33:40
Cellよりまし。ソースは私。
195デフォルトの名無しさん:2010/12/20(月) 17:36:46
具体的にはどうマシなわけ?
Cellの難しさなんてSSE+α程度だったと記憶してるけど?
196デフォルトの名無しさん:2010/12/20(月) 18:12:39
SPUはパイプラインを切った貼ったやらんとパフォーマンスでないのよ。
単に動かすだけならSSEより楽なくらいだけど。
CUDAはFermiになるとキャッシュが利くから結構横着できるからね。
197 ◆0uxK91AxII :2010/12/20(月) 19:58:09
SSEとか無関係だし。

VC7.1の場合、大雑把にloopの中身。
case 1
movaps xmm0,xmm1
cmpeqps xmm0,xmm1
addps xmm2,xmm0

case 2
cmpeqps xmm0,xmm0
addps xmm1,xmm0
明らかに変数宣言をループの外に出したほうがいいな
てかstatic constじゃ駄目なのか?

AVXでOpcode空間に余裕ができたからNANDやNORがようやく実装されるんじゃないかと期待
199デフォルトの名無しさん:2010/12/20(月) 22:24:40
>>198
あれ、団子の割にそんな事言っちゃうの?
それとも俺が確認不足かな。

最適化を有効にしたらループの中で変化しない演算はループの外に出るはずだし
static constにしなくても_mm_set1_pxxみたいのは定数のロードになってるはずだけど。

ただし、
float PI=3.14;
__m128 PI4=_mm_set1_ps(PI);
でこのあとPI4しか使わなければPI4は定数として用意されるけれど、PIを別の場所で使っているとオブジェクトにはPIだけ用意されてPI4を作り出す為にシャッフルする事が稀にあるのは知ってる。

あとgccなんかはstatic const __m128とかやろうものならむしろ無駄なコードを吐く。
200デフォルトの名無しさん:2010/12/20(月) 22:57:06
gccを使うべきでない理由がまた一つ増えたな。
ぶっちゃけアセンブラでしか弄ってないもんで。
スカラ演算ベースだったらCでやっちゃうけど(最近のVC++は本当に優秀)

Intrinsicsは機械語とほぼ1:1で対応してる分、最適化が阻害される部分もあるんで
整数のコードに関しては最近はCでスカラ演算ベースで書いてアセンブリコード
吐き出してからそれを並列化するようなやり方でやってる。

ビット演算を組み合わせるところなんか、本当にVC++は賢い。
202デフォルトの名無しさん:2010/12/21(火) 00:10:59
> Intrinsicsは機械語とほぼ1:1で対応してる分、最適化が阻害される部分もあるんで

ここに完全に同意。
ベクタ長を意識しなきゃいけないシーンが多過ぎる事、命令が変態過ぎてコンパイラが自動ベクトル化しづらい事、Intrinsicsと1:1なせいで自動的な最適化があまり望めない事、
そこら辺はGPGPUの方が若干目があるなあと感じている。
203デフォルトの名無しさん:2010/12/22(水) 19:16:09
intrinsics のいいところは、値がメモリに割り付けられててもレジスタ上にしかなくても同じコードで済むところ。
204デフォルトの名無しさん:2010/12/24(金) 06:15:37
205デフォルトの名無しさん:2010/12/24(金) 12:52:03
Intel(R) Software Development Emulator Release Notes
http://software.intel.com/en-us/articles/intel-software-development-emulator-release-notes/

> 2010-12-21 version 3.88
> * Support for the POST-32NM processor instructions in the 008 revision of the Intel(R) AVX programmers reference document
Visual Studio 2010 SP1でXOP/FMA4/LWPなどのAMD独自新命令に対応の模様
207デフォルトの名無しさん:2010/12/24(金) 20:49:04
What's New in Visual Studio 2010 SP1 Beta
http://msdn.microsoft.com/en-us/library/gg442059.aspx
208デフォルトの名無しさん:2010/12/24(金) 21:36:45
AVX 第3版 以前
VFMADDPD __m128d _mm_fmadd_pd (__m128d a, __m128d b, __m128d c, const int ctrl);
VFMSUBPD __m128d _mm_fmsub_pd (__m128d a, __m128d b, __m128d c, const int ctrl);

AVX 第4版 以降
VFMADD???PD __m128d _mm_fmadd_pd (__m128d a, __m128d b, __m128d c);
VFMSUB???PD __m128d _mm_fmsub_pd (__m128d a, __m128d b, __m128d c);

VS2010 SP1 FMA4 intrinsics
VFMADDPD __m128d _mm_macc_pd (__m128d a, __m128d b, __m128d c);
VFMSUBPD __m128d _mm_msub_pd (__m128d a, __m128d b, __m128d c);
> VFMADDPD __m128d _mm_fmadd_pd (__m128d a, __m128d b, __m128d c, const int ctrl);

Intel FMAに第4引数なんて元々ないよ。imm8の3つ目のソースオペランドとして使って残り4ビットは予約。
AMD版FMAの_mm_macc*って命名則はSSE5由来だが対応する命令はAVX第3版までのFMA仕様にすげ変わってる。
210デフォルトの名無しさん:2011/01/10(月) 01:34:19
Sandy発売したのに
ベータ版のサービスパック入れられない人もいるのよ
俺はAVXの先に興味を持ちました。
Bulldozerまだかよ
シミュレータでさっさと出して欲しいですな。
213デフォルトの名無しさん:2011/01/13(木) 02:02:37
Intelのマニュアルのハードコピーって無くなってたんだ。
AVX版が出るまで待とうと思ってずっと我慢してたのに。
GARAPAGOSにPDFリーダーついてたら10インチ買うわ。
215デフォルトの名無しさん:2011/01/14(金) 09:21:53
配布してる同期ソフト経由で転送してPDF見られるらしいけど、見開きで表示できなかったり
画像としてしか表示できなかったりして、色々と残念な出来らしい。
画面解像度だけみて大きくて見やすいだろうからとPDF目的で買うとガッカリするレベルだそうな。
216デフォルトの名無しさん:2011/01/14(金) 18:11:12
ここで薀蓄垂れてる奴なら、ハックして自家製ビューア走らせるくらい朝飯前だろ?
やっぱりAdobe Readerそのものが必要だな。
Atomタブレット待ちか。
218デフォルトの名無しさん:2011/01/14(金) 20:08:17
AVX試した奴いないの?
linuxならKernel最新にすりゃできるよな?
報告よろ
別に開発だけなら今回はシミュで十分だしな。
prefetch距離とかの調整くらいはやりたいけど。
220デフォルトの名無しさん:2011/01/15(土) 01:09:44
団子は自作板の方でSandybridge出たら買って遊ぶとか言ってなかった?
Win7SP1待ち?
221デフォルトの名無しさん:2011/01/15(土) 01:28:01
口先だけで、金も腕もないってとこなんじゃないの
222デフォルトの名無しさん:2011/01/15(土) 01:41:36
>>216
GALAPAGOSにそこまでするだけの価値を見いだせない。
機能限定されすぎたタブレットPCのできそこないにすぎず、ちょっと機能が増えただけの電子書籍専用端末でしかない。
Androidマーケットでアプリ追加することすらできないんだぜ?
サイズ的には良い感じなんだけどね。Mebius辞めて何を作るかと思ったらこれだからな。
アップデートに期待したいところだが。

実機環境は枯れるまで待ち、というかノートの春モデル待ち。
何か問題出た場合にソフトの不具合なのかハードの不具合なのかわからないってのが一番厄介だから
自作をすべきではない、という経験論。
224デフォルトの名無しさん:2011/01/15(土) 18:35:14
なんで AVX には bsr/bsf が無いんだよ。
なんで必要だと思ったの?

ただ4並列/8並列でbsr代替はできるよ。
(v)cvtpi2psで指数部抽出できるだろ。あとはわかるな。
226|ω・`):2011/01/15(土) 23:25:09
ローテートください
227デフォルトの名無しさん:2011/01/16(日) 11:21:36
>>225
将棋のbitboardで必要だろう。jk
228デフォルトの名無しさん:2011/01/17(月) 05:51:42
そんなどうでもいい用途向けに専用命令つくれとか
もっと意義のある事をあげろよ
229デフォルトの名無しさん:2011/01/17(月) 07:34:48
圧縮やら浮動小数やらいくらでもある。
x86始め、よく実装されているのは必要とされているからだ。
230デフォルトの名無しさん:2011/01/17(月) 19:43:53
CPUに実装されないのは「必要とされていないから」だろ。
231デフォルトの名無しさん:2011/01/17(月) 19:58:26
>>230
何らかの事情で出来なかったも考慮したほうがよいのではないでしょうか。
232デフォルトの名無しさん:2011/01/17(月) 20:08:36
そういう場合は代替がある。
233デフォルトの名無しさん:2011/01/17(月) 20:27:55
このスレで一番賢くてSSEに詳しい人に質問。

__m128i ptn = { 0,4,8,12, 16,20,24,28, 1,5,9,13, 17,21,25,29};
__m128i ptn2={ 0,4,8,12, 1,5,9,13, 2,6,10,14, 3,7,11,15};
__m128i v0 = _mm_load_si128((__m128i*) p1);
__m128i v1 = _mm_load_si128((__m128i*) p2);

__m128i v2 = _mm_shuffle_byte(v0, v1, ptn); ←v0とv1を連結して8bit x 32個の要素の中からptnで指定したものだけを並べる
__m128i v3 = _mm_load_shuffle_byte((__m128i*) p3, ptn2);  ←8bit x 16個の要素をメモリから読み出し、ptn通りに並べ変える

SSEにこんな感じの命令はありませんか?
無い場合、SSE3までの範囲で代替しようとすると、どのくらい複雑になって遅くなりますか?
日本ローカルのボードゲームの解法ごときに貴重なOpcode空間を割くのは無駄だからにきまってるだろ
とはいっても、cvtdq2psのような命令がある以上、4並列のビットスキャン回路は実装されてるわけだが。
235デフォルトの名無しさん:2011/01/17(月) 20:41:34
>>233
本当に任意のパターンであればSSSE3が使えるかどうかによってだいぶ変わる。

SSSE3が使えない場合はパターンの規則性によってだいぶ変わる。
233に特化したやり方でこのスピード、ちょっとでも並びが変わると格段に遅くなる
とかあり得るので、「233の場合」という質問はアリでも「233みたいな場合」とか曖昧な質問は無しな。
236デフォルトの名無しさん:2011/01/17(月) 21:08:37
できれば>>233のパターンに限定しない方向でお願いします。
>>233
1行目が釣りくせえええええ

packssdwの32ビット値の下位16ビットの最上位が1の場合って飽和処理されるんだっけ?w
pshuflw/pshufhwで並べ替えてからpshufdで詰めるか

あとは8ビットおきにマスクしてpackuswbで詰めればOK
238デフォルトの名無しさん:2011/01/17(月) 21:26:23
>>236
限定しないなら答えようが無い。
基本SSSE3の_mm_shuffle_epi8とSSE2の_mm_shuffle_epi16, _mm_shuffle_epi32を使ってどうにか出来なそうなら諦めるしか無い。

ちなみに複雑さに興味があるようだから例を挙げておくと
ptn2はshuffle x 2+unpack x 3回で作れる。
ptnの計算量は一度ptn2 x 2+unpack x 1回になるので、素直にバイト配列でも良いと思う。
>>236
方法など無い。テーブル参照して16回ロードすべし。以上。
ただ、32ビットずつ纏めてからmovdでxmmレジスタに転送したほうが速いかも知れないね。
240デフォルトの名無しさん:2011/01/17(月) 21:30:30
>>237
ん?そんな簡単に出来るの?
packsは飽和処理がうざいよな。飽和無しバージョンを作って欲しい。
241デフォルトの名無しさん:2011/01/17(月) 21:32:47
わかりました。SSEって不便なんですね。
242デフォルトの名無しさん:2011/01/17(月) 21:36:40
>>241
Core1世代は諦めろ。
任意のパターンはshuffle_epi8が使えないとどうにもならんし、逆に使えればptn2は1発だ。
243デフォルトの名無しさん:2011/01/17(月) 21:57:57
Intel製のCPUとかちょっと使いたくないんです。
AMD製に同様の命令が追加されたりしませんかね?
244デフォルトの名無しさん:2011/01/17(月) 22:01:18
VS2010のデバッガ上でYMMレジスタが表示できないんだけどなぜ?
[AVX] と [AVX 浮動小数点] がグレー表示になってる。

CPUはSandyBridgeでWindows 7 のSPもあてたんだけど。
245デフォルトの名無しさん:2011/01/17(月) 22:56:49
>AMD製に同様の命令が追加されたりしませんかね?
釣り確定
246デフォルトの名無しさん:2011/01/18(火) 02:44:51
>Intel製のCPUとかちょっと使いたくないんです。

煽り確定
247デフォルトの名無しさん:2011/01/18(火) 09:04:41
使いたくないならコンパイラの最適化に丸投げでいいんでねーの
248デフォルトの名無しさん:2011/01/18(火) 23:51:39
プリフェッチ命令は1回の発行で何バイト読み込むんですか?
32バイトから128バイトという曖昧な情報もあれば、
1ライン読み込みなので64バイトと言う情報もあります。
命令なので後者のほうが正確のような気がするのですが、認識は合っているのでしょうか?
249デフォルトの名無しさん:2011/01/18(火) 23:54:34
CPUの型番で違う、ってのが答えだったような。
250デフォルトの名無しさん:2011/01/19(水) 00:21:12
Pentium IIIは32バイト
Athlon XPは64バイト
Pentium 4は128バイト
Pentium Mは64バイト
だったような
251デフォルトの名無しさん:2011/01/19(水) 00:23:55
>>249
となると、
Pen4はラインサイズが64バイトなので64バイト、
C2Qも同様に64バイト、ということでよろしいのでしょうか?
252デフォルトの名無しさん:2011/01/19(水) 00:33:49
>>250
ありがとうございます。
微妙に情報が食い違っていたりするので、
もう少し調べてみます。
CPUIDでキャッシュラインのサイズ調べるのが確実だよ

t1 = L1D
t2 = L2
nta = LLC

ただしPentium 4はt1でもt2でもL2までしかフェッチされない
↑訂正
t0とt1読み替えてね

255デフォルトの名無しさん:2011/01/19(水) 01:58:10
>>253
C2Dは64バイトでした。
他のマシンでも調べてみます。
ありがとうございました。
256 ◆0uxK91AxII :2011/01/19(水) 10:40:00
>>253
>nta = LLC
えっ。
257デフォルトの名無しさん:2011/01/19(水) 11:52:14
FMAってIvy Bridgeになったら搭載されるの?
それとももっと後?
>>256
ボケたな・・・

t0 = L1D (Pentium 4は例外)
t1 = L2
t2 = L3(LLC)
nta = L1D(Non Temporal)
259デフォルトの名無しさん:2011/01/19(水) 18:28:14
>>257
Haswellのよてい
260デフォルトの名無しさん:2011/01/26(水) 20:48:00
MASMでAVXプログラミングしてる人いませんか?

MASMで32バイトアラインメントで静的変数を確保したいんだけど、
方法がわかる人いませんか?
VS2010付属の ml64.exe です。

align 16 ならできるんだけど、
align 32 はダメみたい。

今はビルドしてずれてたら詰め物を手動で入れてます。
IntelはYASMがお墨付きだしMASMなんて使わないに越したことはないけど。

ちなみにNASMは色々腐ってるので使用禁止レベル。
たとえば、コード上でalignマクロを使うと、VEXが常に3バイトだと仮定して詰め物をするんだよね

align 16
 vxorps ymm0, ymm0, ymm0
 vxorps ymm1, ymm1, ymm1
 vxorps ymm2, ymm2, ymm2
 vxorps ymm3, ymm3, ymm3
align 16 ;; ←ここが問題
262|ω・`):2011/01/26(水) 22:01:10
何も問題ないけど

use64
vxorps ymm0, ymm0, ymm0
align 16
vxorps ymm8, ymm8, ymm8
align 16
db 0ffh

00000000 C5FC57C0
00000004 90<rept>
00000010 C4413C57C0
00000015 90<rept>
00000020 FF
ん?直ったのか?
264デフォルトの名無しさん:2011/01/26(水) 22:20:42
>>181
今更だが...

浮動小数点例外を有効にして無いならこれでもいい。
_mm_cmpnlt_pd
_mm_cmpnlt_ps

AVXでYMMをすべて1にする場合は、
VCMPTRUEPD
VCMPTRUEPS
というぴったりな命令がある。
(VCMPNLT_UQPDとか他にもいろいろあるけど)
265デフォルトの名無しさん:2011/01/26(水) 22:26:50
>>261
YASMだと align 32 が使えるの?
FP比較は遅いからvpcmpeqb *してvpinsertf128でいいよ。
128ビットまでならロードしたほうが速いかも。ブロードキャストすればデータセクションの容量も食わないし
>>265
64でも128でもいけるよ。
268|ω?:2011/01/26(水) 22:32:49
4096
269デフォルトの名無しさん:2011/01/26(水) 23:03:23
>>266
ロードは128bitも256bitも同じ速さだと思う
いいや。
Loadユニットは128ビットが2本。
256ビットロードは1ポートを2サイクル分消費する。

あと、32/64ビット→128ビットのブロードキャストはロードユニットだけでできるので
わざわざ大きいテーブル用意する必要も無くなる。
271デフォルトの名無しさん:2011/01/27(木) 05:22:59
団子さんも勘違いしてる事が稀によくあるから、自分で実際に検証してみた方がいいぞ。
あのな・・・
シミュレータでの動作検証からはじまって足掛け1年半はAVX触ってるんだぞこっちは

せめてこれくらい読んでから言ってくれ
http://www.intel.com/Assets/PDF/manual/248966.pdf
273デフォルトの名無しさん:2011/01/27(木) 08:32:05
>>270
ヒント
32/64ビット→256ビットのブロードキャスト
vmovdqa (128b load)        Load×1
vmovdqa (256b load)        Load×2
vbroadcast{ss,sd} (128b)      Load×1
vbroadcast{ss,sd,f128} (256b)   Load×1+ FP_Permute
275デフォルトの名無しさん:2011/01/27(木) 19:13:18
団子さんってトリップ検索以外もやるの?
実質6年前に辞めてるけど?
277デフォルトの名無しさん:2011/01/27(木) 20:25:29
団子さんの目って ´  ` ですか?
それとも ・  ・ ですか?
278デフォルトの名無しさん:2011/01/27(木) 22:06:39
>>266
レイテンシはあるけどPort1を1クロックだけ使うだけだから
使える場面は多いかと。
最良は3つを使い分けることか。

| Num of | Ports pressure in cycles | |
| Uops | 0 - DV | 1 | 2 - D | 3 - D | 4 | 5 | |
------------------------------------------------------------
| 2^ | | | | 1 | 1 | X | X | | 1 | CP | vbroadcastss ymm0, dword ptr [0x0]
| 1 | | | 1 | | | | | | | CP | vcmpps ymm0, ymm0, ymm0, 0xf
| 1 | 1 | | | | | | | | X | | vpcmpeqb xmm0, xmm0, xmm0
| 1 | | | | | | | | | 1 | | vperm2f128 ymm0, ymm0, ymm0, 0x0
FP演算の場合はport1とport2は利用頻度高くてport5はレジスタ間mov(AVXの場合は基本的に使わない)や
シャッフル、ブレンド程度しか使わないから、port5積極利用で良いと思うけどな。
これも場合によるか。
280デフォルトの名無しさん:2011/01/28(金) 03:59:26
>>277
・の方。一行目のは公家が描いてる眉と同じ。
AAでは上が見切れてるけど烏帽子被ってる。
麿は団子が食いたいのじゃ
282デフォルトの名無しさん:2011/01/28(金) 21:01:25
>>279
負けず嫌いなだんご。
だんごより大福の方がうまいし。
うるせえおれはだんごがくいたいんじゃ

というか、256ビット(SIMD-FP)でALL-Fなビットパターンが必要な処理って何があるんだ?
絶対値をとるために0x7FFFFFFFとかならまだわかるんだが。
284デフォルトの名無しさん:2011/01/28(金) 23:49:54
多くのCPU向けにSSE2までに制限してプログラムを書いてるんだけど
Core2以降がそれより前のものと比べてSSE1〜4.1が急に倍速化してるけど何か革新があったの?
タイムスリップして来た人乙
64ビットSIMDユニットで128ビット命令を2サイクルかけてたのが128ビットで1サイクルになった。
286デフォルトの名無しさん:2011/01/31(月) 21:13:23
>>283
NaN作成の為に決まっとろうが。
287デフォルトの名無しさん:2011/01/31(月) 21:25:48
上位下位128bitをまたいだPermute命令がほしかった。

VPERMPD ymm1, ymm2/m256, imm8
288デフォルトの名無しさん:2011/01/31(月) 21:29:18
単純にSSEx2ってわけじゃないのが使いづらい。
パック、アンパック、cvtが面倒。
AoS推奨
290デフォルトの名無しさん:2011/02/01(火) 08:04:39
今回Phenomとはまた違ったきな臭さを感じていたが、
プロセッサではなくチップセットに問題があったか。

ttp://plusd.itmedia.co.jp/pcuser/articles/1102/01/news018.html
291デフォルトの名無しさん:2011/02/02(水) 14:37:46
仮想環境でAVXは使えないのか
ホストOSは仕事の都合上古めのLinuxじゃないと駄目なので
ゲストで使いたいのだがcpuidのフラグが立たん
292デフォルトの名無しさん:2011/02/02(水) 21:10:01
xgetbvのOSサポートのフラグじゃなくて?
cpuidによるCPU対応のフラグも立たない?
293デフォルトの名無しさん:2011/02/02(水) 23:24:40
そうなんですよ
ホスト(RHEL5)だとOSXSAVE以外の必要なフラグは立ってるのだが
ゲスト(SL6beta on VMWare Player)だとAVXのフラグすら立たない
294デフォルトの名無しさん:2011/02/10(木) 16:33:51
Win7のSP1がもうすぐのようだな
これでAVXガンガン効かせられる訳だ ったんだがな
295デフォルトの名無しさん:2011/02/16(水) 13:57:54
SIMD命令ってなんで高級言語でかけないんだ
GPUでは当たり前にできるのに
296デフォルトの名無しさん:2011/02/16(水) 14:04:15
OpenCLでかけるようなるとかならないとか。。。
297デフォルトの名無しさん:2011/02/16(水) 14:09:01
どっちだよ
298デフォルトの名無しさん:2011/02/16(水) 15:59:11
intrinsics で充分だろ。
299デフォルトの名無しさん:2011/02/16(水) 22:08:03
x86デコーダが適当な命令をSIMDに読み替えてくれれば解決
名付けてウルトラスーパースカラー
300デフォルトの名無しさん:2011/02/17(木) 10:21:06
>intrinsics で充分だろ。
高級言語だからARMでもPowerPCでもコンパイル通(ry
301デフォルトの名無しさん:2011/02/22(火) 16:11:00.98
石に依存する部分をコンパイラに丸投げするなんて信用できねえ。
というか、データ構造の設計がしにくくなるから、絶対に嫌。
NASM/YASMのマクロの構造体機能なにげに活用してるわ
303デフォルトの名無しさん:2011/03/06(日) 20:52:16.61
__m128を動的に確保するには_aligned_malloc()を使う。
__m128をメンバに持つクラスAも_aligned_malloc()を使う必要があるのは
まあ許すとして、
クラスAをメンバに持つクラスBも_aligned_malloc()を使う必要があるの?
もしそうなら、とてもライブラリ作りにくいんだけど、そういうものなのかな?
304デフォルトの名無しさん:2011/03/06(日) 22:31:11.32
_mm_movelh_ps()と_mm_movehl_ps()って
なんでストアされる組み合わせが逆なの?
嫌がらせ?
305デフォルトの名無しさん:2011/03/06(日) 23:47:06.94
>>303
そういうもんです。
__m128を少量メンバにするならdoubleやfloatで良いし、
大きな配列ならクラスの中で動的確保しる。
306デフォルトの名無しさん:2011/03/07(月) 04:15:11.25
>>303
まず、根本的な問題として、C++なんか使うべきじゃあない。
クラスなんて非効率なものを使うのに、効率重視のintrinsics使うのはおかしい。
307 ◆0uxK91AxII :2011/03/07(月) 09:52:08.08
>>303
使えるなら、__declspec (align () )
308デフォルトの名無しさん:2011/03/07(月) 22:07:52.97
>>306
クラスだから非効率は間違い
作り方によって効率的にも非効率的にもなる
309デフォルトの名無しさん:2011/03/07(月) 23:00:24.87
>>306
今時はHLSLだって、クラス使うのよ
時代は変わっていくんだよ

>>307
それヒープには効かないのよ
xmmintrin.hに_mm_alloc()って有るはずだけど、使えない環境ではこんな感じでやってるぜ

void * aligned_alloc(int count, int align_bytes) {
  void* addr = malloc(count + align_bytes);
  int offset = (int)addr & align_bytes;
  addr = (addr + align_bytes) & ~(align_bytes - 1);
  ((unsigned char*)addr)[-1] = offset;
  return addr;
}

void aligned_free(addr) {
  free(addr - ((unsigned char*)addr)[-1]);
}


C++を使いたい理由は明解だ。
_mm_add_ps(a, b)って書くよりa + bって書きたいじゃん。

つか、virtual継承さえ使わなきゃクラスってそんなに重たくならんよ。
311デフォルトの名無しさん:2011/03/08(火) 17:14:45.18
AVXを試してみた 不良チップセットでだけど
win7、VC2010expressイントリでコンパイルし、除算がSSE2の倍かかるんだが…
312デフォルトの名無しさん:2011/03/08(火) 19:55:13.27
>>311
除算はご丁寧に128bitずつやってる糞仕様だから
ニュートン法を使った方が最後の1ビットまで計算しても速いと思うよ。

Intelはマジこういうのやめてほしいけどね。正常進化を阻害すると凝った事する訳じゃないのにプロセッサ特有の最適化が必要になっちゃって、Pen4の二の舞。
313デフォルトの名無しさん:2011/03/08(火) 22:08:25.45
c++ならtryが出来るよので、俺はnewを使うよ。

>C++を使いたい理由は明解だ。
>_mm_add_ps(a, b)って書くよりa + bって書きたいじゃん。

>つか、virtual継承さえ使わなきゃクラスってそんなに重たくならんよ。

gccなら、オーバーロードしなくてもそのままで使える。
314デフォルトの名無しさん:2011/03/09(水) 21:56:18.07
>>312
除算はスーパーコンピューターだって遅いんだよ。

AVX除算速度と、回路規模、コスト、消費電力、クロック、開発期間、....
を天秤にかけて今の仕様になってんだよ。
ただ1個の要素だけ見て糞仕様とか、ド素人丸出し。
315311:2011/03/09(水) 22:00:37.52
SSE2の除算より遅いと書いたと思うが
素人丸出しか?
AVXのが2倍速いとふつう思わんか?
素人で悪かったな
316デフォルトの名無しさん:2011/03/09(水) 22:14:44.79
>>315
そりゃ256bitを128bitずつ2回に分けてるんだから当たり前だ。
317311:2011/03/09(水) 22:16:46.51
>>316
SSE2でやっても128×2でやるんだから同速だろ
そういう素人意見が聞きたいんじゃないんだが
318デフォルトの名無しさん:2011/03/09(水) 22:33:15.42
>>317
128bit 単精度 スループット14 レイテンシ14
256bit 単精度 スループット28 レイテンシ29
319デフォルトの名無しさん:2011/03/09(水) 22:56:55.11
実行時間を計ってみた

divps xmm0, xmm1
183クロック

vdivps xmm0, xmm0, xmm1
183クロック

vdivps ymm0, ymm0, ymm1
203クロック

確かに異常に遅いな。
エラッタがあってマイクロコードで実行してるとか?
320デフォルトの名無しさん:2011/03/10(木) 08:58:00.63
まあ、普通は除算は使わないようにするわな。
321デフォルトの名無しさん:2011/03/10(木) 20:03:56.23
>>319
普通の数じゃないと極端に遅いみたいだ。
普通の数だと

divps xmm0, xmm1
12.7クロック

vdivps xmm0, xmm0, xmm1
12.7クロック

vdivps ymm0, ymm0, ymm1
25.3クロック

くらいだった。
値によって変わる模様。

インテルのドキュメントには範囲じゃない記述だったので
値によらずに同じクロックかと思ったのだが。

>>311>>312 が何を騒いでるのか意味不明。
322デフォルトの名無しさん:2011/03/10(木) 20:17:04.16
128bitの場合、
割る数、割られる数のどちらかが 0.0, NaN, ∞ の時は9クロックくらい。
割る数が2^nの時も9クロックくらい。
結果がアンダーフローや非正規数の場合と、割る数、割られる数のいずれかが非正規数の場合は183クロックくらい。
結果がオーバーフロー、割る数と割られる数が同じ、等は普通どおりの時間。
323デフォルトの名無しさん:2011/03/10(木) 21:07:01.21
せめてSIMDだけでもいい加減デノーマルやめてほしいわww
324デフォルトの名無しさん:2011/03/10(木) 21:59:45.78
>>323
デノーマルも不要だが、
個人的には無限をなくしてほしい。
異常値検出のNaNのはずが、
無限があると、大小比較が出来てしまっておかしいことに。
0.0がプラスかマイナスかなんて意味が無いのに、
1.0/0.0 が+無限、
1.0/-0.0 が−無限、
で、1.0/0.0 > 1.0/-0.0 が成り立ってしまう。
これを決めた人は頭が悪すぎる。
325デフォルトの名無しさん:2011/03/10(木) 22:02:04.87
あの子の性癖はアブノーマル
326311:2011/03/10(木) 22:03:22.76
>>324
1.0/0.0 > 1.0/-0.0
これ成り立つんだけど
327デフォルトの名無しさん:2011/03/10(木) 22:34:57.73
>>326
成り立つから良くないと書いてるんだけど。
328311:2011/03/10(木) 22:50:16.74
y=1/xの話だよ
x=0近傍での話
実際に発生しうるってことね
329デフォルトの名無しさん:2011/03/10(木) 22:55:53.76
>>324
基本的に入力が悪い場合は入力の責任にできる環境にあるので今まで出くわした事が無いが、
確かに使いたい場面が滅多に無いのに凝ってるのはひどい仕様だな。

ただ-0.0はSIMDで符号ビットをマスクするために使わせてもらっているので無くさないで欲しいw
SSE2からは_mm_castsi128_ps(_mm_set1_epi32(0x80000000))ってできるので、
SSEの時に適切にintからキャストする方法を用意しなかったIntelが悪いんだけどな。
330デフォルトの名無しさん:2011/03/10(木) 23:01:03.88
>>328
+0.0 と -0.0 がある理由は、
単に符号反転がしやすい為。
実際、+0.0 = -0.0 が成り立つので、
+0.0 と -0.0 は同じ値の別表現だという意味である。
ところが、除算をするといきなり大小が大きく違う数になってしまう。
一貫性がまったくない。
Unordered にしておけば良かったのに、
何を血迷ったか Ordered にしてしまった。
Unordered だったらここまで不満は無かった。
331311:2011/03/10(木) 23:06:20.74
>>330
>>除算をするといきなり大小が大きく違う数になってしまう
数学的にそれが答えだから仕方ないでしょ
332デフォルトの名無しさん:2011/03/10(木) 23:12:11.81
>>331
数学をしらない人間が数学を語るとは.....

数学的には、
+0と-0があって、同じもの同士を引いて+0にはなるが-0にはならない
なんて非対称な代数系は普通は使わない。
実数から0を除いたものに、±0と±∞を足したものは、
まともな代数系にならないことくらい周知の事実だ。

コンピューターも数学ももうちょっと勉強しなさい。
ド素人クン。
333311:2011/03/10(木) 23:14:21.02
>>332
>>328が理解できないかな?ド玄人君
334デフォルトの名無しさん:2011/03/10(木) 23:23:35.88
>>332
おまえ、数学素人だろw
335デフォルトの名無しさん:2011/03/10(木) 23:28:03.89
考えられる実装は以下
A. +0と-0を同一視、+∞と-∞を同一視でUnordered、0による除算は∞
B. +0と-0を同一視、+∞と-∞は別でOrdered、0による除算はNaN

>>333
lim_[x→1.0] {1/(x-1.0)}
これは、xがプラス側、マイナス側のいずれから近づくかで+∞、-∞のどちらに発散するかが決まる。
ところが、コンピューター界では 1.0/(1.0-1.0) は-∞ではなく+∞だと定めている。
これには数学的根拠は全くない。
336デフォルトの名無しさん:2011/03/10(木) 23:32:04.81
>>334
フィールズ賞をとったことが無いって意味では素人かもね。
337デフォルトの名無しさん:2011/03/10(木) 23:36:29.93
つーか-0.0なんてどうやったら演算結果に出るんだよw
意図的に使わなければありえないだろ
個人的には
1.0/0.0=+Inf -1.0/0.0=-Inf
1.0/-0.0=NaN -1.0/-0.0=NaN
にしてほしい
338311:2011/03/10(木) 23:37:38.58
>>335
お前さ〜昨日の>>316だろ?
お前はレベル低いからもういいよ、素人回答すんなよ
339デフォルトの名無しさん:2011/03/10(木) 23:39:44.00
0.0は限りなく0に近い切り捨てられた値として、-0.0は完全な0としてみなす仕様が欲しいってこと
340デフォルトの名無しさん:2011/03/10(木) 23:41:11.49
>>337
ゼロ以外の普通の値に対して、
a*(b+c) とするだけでも出てくる可能性がある。
341デフォルトの名無しさん:2011/03/10(木) 23:50:11.84
どうせ無限なんてでてくるのは異常値なんだからNaNで良いよ。
NaNはたくさんの種類が作れて、
勝手に自分で意味をつけられ、
その意味を伝搬していける。
中途半端な仕様の無限なんて不要。
342デフォルトの名無しさん:2011/03/10(木) 23:50:38.26
>>340
bとcが正規数ならεはDBL_MINと同じか大きいから
abs(b+c)>=DBL_MINかabs(b+c)=0.0
だろ?
abs(a)<1.0だとしても計算時にデノーマルするだけで格納される値は
abs(a*(b+c))>=DBL_MINかabs(a*(b+c))=0.0
じゃないの?
具体的にはどんな値を入れれば出るんだ?
343デフォルトの名無しさん:2011/03/11(金) 00:01:40.86
>>342
a=-1.0
b=1.0
c=-1.0
344デフォルトの名無しさん:2011/03/11(金) 00:05:00.73
>>343
b+c= 1.00000000000000 + -1.00000000000000 = 0.00000000000000
a*(b+c)= -1.00000000000000 * 0.00000000000000 = 0.00000000000000
な気がするけどちょっと試してみる
345デフォルトの名無しさん:2011/03/11(金) 00:13:16.51
お、できた
俺の認識が間違ってたみたいですまん
double a, b, c, d;
a = -1.0;
b = 1.0;
c = -1.0;
d = a * (b + c);
if(d < 0.0){d = 2.0;}
だとdは2.0じゃなくて-0.0のままなのが納得いかないけどw
346デフォルトの名無しさん:2011/03/11(金) 00:29:15.92
>>345
-0.0 と +0.0 は同一視の為、-0.0 < +0.0 は偽で、
-0.0 = +0.0 が真になる。

>>323
デノーマル数を0にしちゃって計算を遅くしないモードがある
MXCSRレジスタのDAZビット
347デフォルトの名無しさん:2011/03/14(月) 21:26:52.77
Ax + b = 0, A=3x3行列 の連立方程式を解く関数を
float(C++)からsse(C++ + 組み込み関数)へ移植したんだが
2倍程度遅い結果。これでも修正が効いた方で
ベタ移植だと30倍ぐらい遅かった。

等速ならまだしも、何倍も遅くなる理由がわからん。
floatだって内部的にsse使ってるのに。
思うんだが、組み込み関数使うと
コンパイラの最適化が相当オミットされてたりしないか?
348デフォルトの名無しさん:2011/03/14(月) 21:32:28.16
そうだよ

SSEを下手に使っても効果ないよ
349デフォルトの名無しさん:2011/03/14(月) 21:37:00.89
そうなの?
だったら、SSEとかAVXとか積まずに
FPUをその分載せてくれた方が
よっぽどマシだなぁ
350デフォルトの名無しさん:2011/03/14(月) 21:43:59.96
上手に使えばいい話
なんでそういう思考になるの?アフォ?
351デフォルトの名無しさん:2011/03/14(月) 21:53:42.11
>>350
だから上手に使った結果2倍遅いんだって。
SISDより遅いSIMDなんていらないじゃん普通。
352デフォルトの名無しさん:2011/03/14(月) 21:56:21.55
>>351
単にSSEに置き換えても早くならないって書いたよね
基本だけどパイプラインとかアウトオブオーダーとか理解してる?
353デフォルトの名無しさん:2011/03/14(月) 22:00:25.16
ていうかSSEの知識ないんだったら>>347の内容くらいBLASで解けばいいじゃん
354デフォルトの名無しさん:2011/03/14(月) 22:02:35.51
>>352
何?組み込み関数を使うと
パイプラインがストールしたり、
インオーダー実行されちゃったりするの?
組み込み関数が遅いのはそんな理由じゃないよね。

つーか速くならないだけならいいんだってば。
現実は遅くなるの。それもとんでもなく。
floatだって、実際のコードはsseを使ってて
量的な差は無いはずなのにさ。
355デフォルトの名無しさん:2011/03/14(月) 22:05:17.14
>>352
当然blasも使ってる。
ちなみにublasとubals相当の関数の比較だと
約5倍は遅い。
356デフォルトの名無しさん:2011/03/14(月) 22:06:12.07
>>354
多少は知識あるじゃん
それでできないんだったらあきらめな
センスなさすぎw
357デフォルトの名無しさん:2011/03/14(月) 22:06:28.66
検証比較ソース出せばすぐ検証して貰えるよ。
358デフォルトの名無しさん:2011/03/14(月) 22:08:47.07
>>354
>コンパイラの最適化が相当オミットされてたりしないか?
これが正解
というか3x3だと最後の使わないデータがコンパイラには理解できないから
FPUはO(3x3)=O(9)
SSEはO(4x4)=O(16)
でコード次第では不利
359デフォルトの名無しさん:2011/03/14(月) 22:09:44.25
つーか、こいつもしかしてintrinsicだと遅いっていってる?
つまりアセンブラなら速いと

こいつ性格悪そうだからそういう意味かもな
360デフォルトの名無しさん:2011/03/14(月) 22:17:31.53
>>358
Ax + b = 0 は、3x4行列として扱う。
__m128 x 4本で無駄は出ない。

>>359
そうだよ。だってアセンブラは対象外だもん。
アセンブラで書くとコンパイラの最適化を阻害して
逆に遅くなるよ派だし。
intrinsicだと許せる理由の他に
許せない理由で遅くなってそうだと思って聞いてみたんだよ。
361デフォルトの名無しさん:2011/03/14(月) 22:18:16.42
>__m128 x 4本で無駄は出ない。
__m128 x 3本の間違い
362デフォルトの名無しさん:2011/03/14(月) 22:18:56.98
データの順番を変えられるなら、
1個ずつ連立方程式を解かず、
8個ずつず解けば速い。
363デフォルトの名無しさん:2011/03/14(月) 22:21:09.33
あ、AVXじゃなくSSEか。
じゃあ4個ずつ。
364デフォルトの名無しさん:2011/03/14(月) 22:41:28.98
>>360
>>アセンブラで書くとコンパイラの最適化を阻害して
>>逆に遅くなるよ派だし。
それはおまえの能力が低いからって言われるよ

ま、最適化より早いコード書くのは大変だけどね
時間かければ可能
365デフォルトの名無しさん:2011/03/14(月) 22:47:25.52
構造体の並び順とか変数の参照回数とかは大抵コンパイラに任せた方が速い
テーブル参照や三角行列化などのアルゴリズムに起因するものは人間が最適化しないといかん
割とテキトーに命令並べてもアウトオブオーダ実行でパイプライン埋めてくれるのでアセンブラで書くよ派
どのポートで実行されるかは意識して書くけどね
367デフォルトの名無しさん:2011/03/15(火) 18:51:54.74
あれ、団子はintrinsic派じゃなかったっけ?
おいらはアセンブラ派。
もちろんどのポートで実行されるかとかレイテンシーとかは考慮する。

>>365
最近は構造体の並び順とかもコンパイラが勝手に並び変えるのか?
でも単純に並び変えてもほとんど恩恵が無いような。
SOAとAOSを最適化で切り替えてくれるならすごい恩恵はあるが、
まさかそんなところまで最適化は出来まい。
それは時と場合によって使い分ける
intrinsicsは緩くかけるからいいんだよC++のinlineとかtemplateと相性いいしね

関数丸ごと最適化の場合はアセンブラ使うよ。
とりあえずMSはYMMレジスタ全てcaller-saveのABI規約作ってくれ
369デフォルトの名無しさん:2011/03/16(水) 00:29:18.14
> それは時と場合によって使い分ける
ふーん。
intrinsicマンセーぶりからしてアセンブラ使えないのかと思ってたよ。

> とりあえずMSはYMMレジスタ全てcaller-saveのABI規約作ってくれ
これはその通り。

> intrinsicsは緩くかけるからいいんだよ
そうだね。
AVXを使って緩くかけるような機会もそんなにないけど。
370デフォルトの名無しさん:2011/03/16(水) 16:39:01.09
団子はこないだ intrinsics ディスってなかったか。

86 の事情は分からんが、ps3 で PPC VMX 向けなら、ひとまず intrinsics で書く。
ターゲットより規模の問題かもしれんけどね。
371デフォルトの名無しさん:2011/03/16(水) 17:26:17.44
VCCだと64bitではintrinsicsしか使えないよね?
372デフォルトの名無しさん:2011/03/16(水) 19:53:23.89
>>371
っMASM etc.
>>370
命令と1:1で対応している分逆にコンパイラの最適化が阻害されるケースがある
とかいったやつか?
所詮はintrinsicsは高級アセンブラだ。
コンパイラより賢いコードがかけるならそれでいいんだ。
アセンブラを使っても同じ。

intrinsicsと対比するなら、むしろコンパイラの自動ベクタライズ機能だ。
CilkとかCtとかまともに使えるならそっちでもいいんだけどな

「緩くかける」ってのはたとえば、SIMDレジスタ16本あっても変数が16以上ある場合なんかあるじゃん。
レジスタカラーリングは常に自分のほうがコンパイラより賢いとは限らない。
32ビットと64ビットで同じコードを使ったり、あるいは、ターゲットCPUごとにコンパイルオプションを変えて
命令スケジューリングをチューンしてみたりとか、そういう場合にある程度有効だと思う。
(32ビット+AVXってなるべく考えたくないな)


最終的にはサポートされてる命令ごとに同じ関数を何個も実装しないといけなくなって
頭がパーン(必須アモト酸が足りない)
AVXのコードは個人的にはYASMが一番書きやすいと思った。
凝り性だから2バイトVEXになるべく収まるように第2ソースオペランドに使う頻度の高い変数は
ymm0-ymm7になるように配置したりとか、そういう試行錯誤もなかなか楽しい。
(当然%define使いまくり)

大きい関数になると流石に諦めたくなる。
375デフォルトの名無しさん:2011/03/21(月) 22:40:07.33
AVXの命令を非対応のCPUに読み込ませたらどうなるんだ?
昔SSE2の整数命令をPen3で実行したらなぜか例外は全く起きず、MMXの相当する命令に置き換わったのか、
前半のエレメントだけ処理されたような形になった記憶があるが…。
376デフォルトの名無しさん:2011/03/21(月) 22:53:23.22
自分でテストしてみりゃいいだろ
377デフォルトの名無しさん:2011/03/21(月) 22:59:47.56
非対応CPUでも、非対応OS上の対応CPUでも例外発生
378デフォルトの名無しさん:2011/03/21(月) 23:46:28.01
>>376
>>377
今あるのはVS2010とVistaとC2Qだけで、
>非対応CPUでも、非対応OS上の対応CPUでも例外発生
のとおりWin7SP1もCi7も持ってないので…。
379デフォルトの名無しさん:2011/03/21(月) 23:51:39.51
結局Win7SP1上で走らせても相当するSSE命令に置き換わるようなことは無く、
処理単位だけ変えて同じ命令を使うようなことは出来ないと考えていい?
380デフォルトの名無しさん:2011/03/22(火) 00:28:30.60
> 昔SSE2の整数命令をPen3で実行したらなぜか例外は全く起きず、MMXの相当する命令に置き換わったのか、
OSが例外を処理してたとか、
Pen3で中途半端にSSE2の実装がされていたとか、
....

AVXの場合はそんなことは無い。
潔くスパッと例外発生。
どちらも対応したければ、
XCR0レジスタでAVX対応かどうか判断して、
対応の場合と非対応の場合で別のコードを走らせる。
381デフォルトの名無しさん:2011/03/22(火) 00:33:23.80
SSE2の、が勘違いだったんだろう
382デフォルトの名無しさん:2011/03/22(火) 01:12:20.94
PentiumIIIのデコーダがprefixを無視するだけ
特殊なことをやっているわけじゃない

http://sandpile.org/ia32/opc_enc.htm
http://sandpile.org/ia32/opc_2.htm
66, F3, F2=意図しないプリフィックスがついてるけど無視しちゃえ

Athlon XPも同じ動きだね
あと、VC++なんかはSEH対応してるから、ためしにAVX命令を実行してみて
例外をキャッチしたら従来命令を実行って手も使えるけどな。
385デフォルトの名無しさん:2011/04/16(土) 01:33:42.21
>>384
普通はそんなアホなコードにはしない。
386デフォルトの名無しさん:2011/04/16(土) 04:04:56.75
普通じゃなくてもしない。

と思ったが、流れ的にその場じゃなくてアプリケーションの先頭でそうやってチェックして、
以降切り替えるという意味なのかも知れないと思い直した。

でもしない。
387デフォルトの名無しさん:2011/04/18(月) 23:50:02.49
>>385
じゃあどうかくの?
最初にcpuidで判別?
388デフォルトの名無しさん:2011/04/19(火) 05:21:52.32
そうだね
SIMD使うような性能重視のコードで、エミュレーショントラップなんてやってたら話にならないし
事前に切り分けるんだったら、例外なんか使う必要は普通ない
389デフォルトの名無しさん:2011/04/19(火) 21:15:17.43
CPUIDだけじゃダメ。
XGETBVを使ってOSが対応しているかどうか調べる。
390デフォルトの名無しさん:2011/05/01(日) 22:37:53.35
>>389
SIMD使うようなコードって、そもそも使うOSとか指定させないか?
そもそも未知のOSで動くバイナリなんて作れないでしょう。
391デフォルトの名無しさん:2011/05/02(月) 00:04:37.45
将来のOSまでサポートできないしi7マシンにXP入れるようなバカも多いし
XPをAVX対応にするようなやつも出てきそうだし
あと今後はXPモードのような仮想環境も考える必要がありそうだし

結論
OS指定は無駄
392デフォルトの名無しさん:2011/05/02(月) 17:13:41.32
現実的には、強制指定の手段をユーザーに提供して、一応自動検出するけれども
ユーザー指定を優先して動作する、でいいんじゃないの?
393デフォルトの名無しさん:2011/05/02(月) 21:20:09.38
>>392
XGETBVの結果で十分
394デフォルトの名無しさん:2011/05/02(月) 22:52:09.89
エラッタ対策としてユーザーが無効化するのは十分にありかも
395デフォルトの名無しさん:2011/05/03(火) 07:44:32.29
>>394
今見つかっていなくて、存在もしないかもしれない重度のエラッタが心配なら
AVXに限らずプログラムなんか組めないと思う。

ユーザーが速度をくらべてニヤニヤする為とかデバッグの為とかならわからないでもないが。
396デフォルトの名無しさん:2011/05/03(火) 08:32:40.26
fdivみたいな計算結果が間違えるようなエラッタだったら選択方式とかありえんし
どんなエラッタだと実行する命令を選択できることが嬉しいんだ
397デフォルトの名無しさん:2011/05/06(金) 20:18:12.67
AVXのほうはどうよ?
SSEより速くなった?
398デフォルトの名無しさん:2011/05/06(金) 23:05:52.73
>>397
そりゃそうよ。ツボにはまれば倍に。
ベクトル化が難しいデータだと活用はSSE2より難しくなるけど。
399デフォルトの名無しさん:2011/05/10(火) 22:48:11.48
ドット積のような計算やってみたんだが水平加算が数が増えた分遅くなるな
とりあえずチューニングがむずい
ちっともはやくならん
400デフォルトの名無しさん:2011/05/10(火) 22:53:58.51
構造体の配列じゃなく、配列の構造体にする。
出来ないなら劇的な速度アップはムリ。
401デフォルトの名無しさん:2011/05/10(火) 23:05:47.94
SOAかAOSとか言ってるレベルではないよ
402デフォルトの名無しさん:2011/05/10(火) 23:37:47.48
データのベクトル化が無理なら劇的な速度アップはあきらめろ。
403デフォルトの名無しさん:2011/05/10(火) 23:56:50.67
AVXは128ビットずれててもセグ違反にもならなず、しっかり計算してしまうぞ?
404デフォルトの名無しさん:2011/05/11(水) 00:06:16.67
256bitアラインメントを要求するのは
VMOVAPD VMOVAPS VMOVDQA VMOVNTDQ VMOVNTDQA VMOVNTPD VMOVNTPS
405デフォルトの名無しさん:2011/05/11(水) 00:10:47.94
それって一切ペナルティ無しで?
406デフォルトの名無しさん:2011/05/11(水) 00:18:24.19
ペンるてぃの有無は分からん
自分で確認してみてくれ
407デフォルトの名無しさん:2011/05/11(水) 20:39:53.95
なんかSSEを2回やってるのと変わらん速度しかでないんだけど
ほとんどの命令で倍近い時間がかかるのは仕様?
408399:2011/05/11(水) 20:46:30.30
同じく
今のところ対応不明
てか速くなるのかな?
409デフォルトの名無しさん:2011/05/11(水) 20:54:48.81
そうか!
>>403が言っている通りならAVX命令は本当にただのSSE命令2回分だ
少し納得
410デフォルトの名無しさん:2011/05/11(水) 22:49:47.40
どんな処理でテストしてるの?
411デフォルトの名無しさん:2011/05/11(水) 23:24:13.81
今は土台を作る時期
412デフォルトの名無しさん:2011/05/12(木) 01:41:23.77
レジスタ同士の演算なら普通に倍の速度は出る。
メモリからのロードは(あんまりここがボトルネックにならないだろうから)工夫して凌ぐ。
413デフォルトの名無しさん:2011/05/13(金) 23:22:44.28
floatの配列の合計を求めるプログラムで試してみたけど、
普通にAVXの方が半分の時間で済むぞ。

アラインメントをずらした実験だと、
128bit境界でないと極端に遅く、
128bit境界であれば256bit境界に無くても速い
414デフォルトの名無しさん:2011/05/13(金) 23:46:33.21
まあロード・ストアは128なんだから不思議でもないんじゃない
ただストアフォワーディングできるのは32Bアラインだけとかいう話だったような
415デフォルトの名無しさん:2011/05/14(土) 00:37:44.73
>>412>>413
>>407=>>409だけど整数演算が完全に1回あたり2倍の時間がかかるんだ
浮動小数は2倍速とまではいかないかったけどメモリロードストアの回数が減った分程度に速くはなった
416399:2011/05/14(土) 00:58:16.19
ドット積は水平加算が馬鹿になんないんだけどいい方法あるのかな?
xmmレジスタに移動してシフトしたりしてるんだけど遅くて駄目だわ
417デフォルトの名無しさん:2011/05/14(土) 08:08:58.82
>>415
整数命令はYMMを使えないが。
何に比べて何が2倍時間がかかると言ってるの?
418デフォルトの名無しさん:2011/05/14(土) 08:11:52.50
>>416
水平演算がいらないようなデータ順にするのが一番。
とりあえず現状のコードを見せて。
419399:2011/05/14(土) 09:17:56.59
>>418 サンクス
イントリでこんな感じ(avxのアセンブラまだ覚えられんのね)

正確にはドット積というよりマトリクス・ベクトル積で4行同時に計算してる

for(j=0;j<m;j+=8)
{
__m256 mulA256 = _mm256_mul_ps(M[i+j], V[j]);
__m256 mulB256 = _mm256_mul_ps(M[i+1+j], V[j]);
__m256 mulC256 = _mm256_mul_ps(M[i+2+j], V[j]);
__m256 mulD256 = _mm256_mul_ps(M[i+3+j], V[j]);
sumA256 = _mm256_add_ps(sumA256, mulA256);
sumB256 = _mm256_add_ps(sumB256, mulB256);
sumC256 = _mm256_add_ps(sumC256, mulC256);
sumD256 = _mm256_add_ps(sumD256, mulD256);
}

→sum(A〜D)256の8つの数値をそれぞれ水平加算する
今はこれをsum256を_mm256_hadd_psとfloat*で二分割してxmmで水平加算してるが、ここで時間食っている

どうぞよろしくです

>>水平演算がいらないようなデータ順にするのが一番。
こんなことできるん?ベクトル演算しなけりゃ可能だろうけど…
420デフォルトの名無しさん:2011/05/14(土) 10:26:30.27
avxならvdpps使えばいいんじゃね
421デフォルトの名無しさん:2011/05/14(土) 10:50:20.26
>>419
なんかよくわからない

水平加算はループの外で行うの?
mが大きい値ならループの外の時間なんて誤差の範囲だから、
mはそんなに大きくない値?
だとするとさらに外側のループが存在する?
それならもうちょっと外側まで書いてほしいな。
422デフォルトの名無しさん:2011/05/14(土) 10:50:31.56
> こんなことできるん?ベクトル演算しなけりゃ可能だろうけど…
やりたい演算や、他のいろんな事情で可能かどうかが決まる。
たとえば5x5の行列と5次元ベクトルとの積をたくさん計算したい場合、
float m[5][5][N];
float v[5][N];
のような構造で持てれば速く計算できる。
でも、この並び順だと他の演算を行う時に都合がわるいとか作りにくいとかだったら
積の時間を犠牲にしてでもデータの並びを変えなくてはならない。
また、行列やベクトルの次元が固定でなければこの並びはちょっと無理がある。
423デフォルトの名無しさん:2011/05/14(土) 10:53:35.88
今後SIMDのベクトル長が伸びれば
さらにデータの並び順決めが重要になる。

AVXはせいぜい8個同時演算だが、
ベクトル計算機なんかだと1024個とかを同時に計算したりする。
424デフォルトの名無しさん:2011/05/14(土) 11:44:55.32
>>422
その並びは水平加算は早いだろうけど他の計算量は全て増えちゃうね
ベクトル井演算の意味無くね?
425デフォルトの名無しさん:2011/05/14(土) 11:45:38.03
井がなぜか紛れ込んだ
無視して
426デフォルトの名無しさん:2011/05/14(土) 12:48:46.34
>>424
どういうコードを想定してる?
ベクトル化がわかってないでしょ。

5x5の行列と5次元ベクトルとの積を普通にやると、
計算量は、乗算25回、加算20回。
_mm256_mul_ps を25回、_mm256_add_ps を20回 で
行列とベクトルの積を8個行うんだよ。
427デフォルトの名無しさん:2011/05/14(土) 13:04:22.44
SIMDを用いた計算へののアプローチは2種類あって、

ひとつは>>426のように、SIMDの要素分データを並列に並べ、並列計算を行う方法。
std::valarrayみたいなもんだと思えばいい。

もうひとつはデータの並列化はせずに、行列の行や列をSIMDレジスタにそのままマップして計算する方法。
D3DXMATRIXのSSE対応とかがそう。>>419もそうかな。

基本的に前者はデータの配置に制限を持つが、無駄がなく効率が良い。
後者はデータの配置に制限は無いが、効率が悪い。
428デフォルトの名無しさん:2011/05/14(土) 13:15:03.33
float m[5][5][N];のNは空にするんじゃなくてデータ入れるのか
なるほど意味理解した
で、あれば速いね
429デフォルトの名無しさん:2011/05/14(土) 13:32:47.40
同じ人かどうかは知らないけど
>>401 みたいに書いてるから
当然ベクトル化の意味がわかってると思ったんだけど
わかってなかったのね
430399:2011/05/14(土) 23:19:55.51
水平加算を避けるのは行列の転置ができればいいってことだね
生憎、それは無理
単純なドット積も他にあるしSSE2とAVXで使い分けするしかないかなぁ
431デフォルトの名無しさん:2011/06/13(月) 07:02:46.00
432デフォルトの名無しさん:2011/06/18(土) 00:51:54.38
>>431
それ位のインセンティブが無いと移行する気が起きないな。
433デフォルトの名無しさん:2011/06/18(土) 18:51:59.69
もうAVX2の話でてんのか
今くらいのタイミングで出るってことは、IvyBridgeに搭載される可能性高そうだな
434デフォルトの名無しさん:2011/06/18(土) 19:09:31.72
整数演算が256ビット化するならIvyBridgeはCore2並に長く付き合える良作になりそうだな
435デフォルトの名無しさん:2011/06/25(土) 21:47:13.68
Ivyは単にシュリンクだけ
じゃなかった?
436デフォルトの名無しさん:2011/06/25(土) 22:28:27.42
いくらか手を入れるとかニュースでみたような。
437デフォルトの名無しさん:2011/06/25(土) 22:51:57.56
IvyBridgeに追加されるのは
post-32nm processor instructionsと呼ばれる
乱数発生命令や半精度浮動小数点と単精度浮動小数点の変換命令
http://software.intel.com/en-us/articles/intel-software-development-emulator-release-notes/
>Support for the post-32nm processor instructions for the processor codenamed Ivybridge

AVX2はHaswellから
http://software.intel.com/en-us/blogs/2011/06/13/haswell-new-instruction-descriptions-now-available/
438デフォルトの名無しさん:2011/07/22(金) 22:25:02.23
Iacaでコード解析したときのperformance latencyって解析範囲を実行するときにかかると思われるサイクル数と理解すれば良いの?
439デフォルトの名無しさん:2011/07/23(土) 06:44:19.87
あんまり参考になんないんだよね
440デフォルトの名無しさん:2011/07/31(日) 08:19:00.59
AVX2はhaswellかぁ
IvyBridgeなら買ったのに
ところで、SandyのAVXって、Core以前のSSEみたいに、
128bitユニット2個使って演算、みたいなことやってるん?
441デフォルトの名無しさん:2011/08/02(火) 08:45:50.48
やってないよ。AVX使えば性能倍になる。Bulldozerは128bitx2。
442デフォルトの名無しさん:2011/08/02(火) 13:30:00.10
443デフォルトの名無しさん:2011/08/03(水) 19:20:10.75
AVX1の整数は128bitのままでしょ。
3オペランド化によるレジスタ割付の改善やコピーの削減による効果はあるだろうけど、
SSE2が登場して、Pen3が急速に時代遅れになっていったのと同じリスク抱えた
代物だと思ってる。
444デフォルトの名無しさん:2011/08/03(水) 19:31:56.36
AVX1は浮動小数点の256bit化が売り。あとはオマケ。
パフォーマンスは256bitの加減算と乗算を同時に1クロックで出来る。
CORE以前のSSEとは異なる。
AVX2は整数命令の256bit化。
445デフォルトの名無しさん:2011/08/03(水) 19:59:05.61
Pen3からCore2までかかってようやく完成したSSEに比べると
Sandyから次のtockのHaswellで完成するAVXは驚異的なハイペースだな
446デフォルトの名無しさん:2011/08/03(水) 22:00:14.46
整数で16並列とか32並列とかプログラマとしては嬉しくないんだけど・・・
SSEでさえ8ビット演算はロードとストアが面倒だし、下手すると遅くなるし・・・
SSEだと特にSSE2の16ビット整数が便利だったからAVXは32ビット整数がメインかな?
と思ったけど今後も一番重いのは画像処理だろうし、画像で32ビットって何に使うんだ?
結局AVXは流行るのか?
447441:2011/08/04(木) 00:06:30.41
>442
ごめんちゃんと調べずに書いてたわ。
- 内部は 128bitx2 になっているが、パイプはFADD/FMULで一本ずつしかないので128bit演算のスループットが倍になっているわけではない(Core以前のSSEとは違う)
- ロードは256bitを128bitx2で使える。なのでスカラのロードもスループット倍になっている
だった。
まあ、256bit浮動小数演算を繰り返すだけなら、256bitのパイプがADDとMULで一本づつある、という理解でいいと思うけど。
448デフォルトの名無しさん:2011/08/04(木) 23:14:48.03
AVXは32bit/64bitの浮動小数点がメイン。
画像も音声も途中の処理は今後どんどん浮動小数点化していく。
449デフォルトの名無しさん:2011/08/05(金) 01:50:35.05
しかし主流の肝心のH.264は浮動小数点を使えない、というか使わない設計になっている。
今のところAVXの出番は無いかもしれん。
450デフォルトの名無しさん:2011/08/05(金) 12:59:50.05
その辺はAVX2まで待ちかな
451デフォルトの名無しさん:2011/08/10(水) 20:55:44.17
低レベルな質問で申し訳ないんですが、x64からインラインアセンブラ
が使えなくなっているのに気づいたのですが、これってどんな理由が
あってのことなんでしょうか?

インラインアセンブラとintrinsicのメリット・デメリット的なものを知りたいです。
452デフォルトの名無しさん:2011/08/10(水) 21:00:36.77
vc2010限定の話だろ
453デフォルトの名無しさん:2011/08/10(水) 22:08:51.50
>>451
理由としてはこんな感じだろうか・・・
・Windowsのx64ソフトウェア呼び出し規約は面倒だからプログラマがミスし易い
・関数のプロローグ/エピローグを指定する新たなキーワードとか作りたくない
・リーフ関数なら楽に作れるけど大した事出来ないからintrinsicで良いんじゃね?
・何で動かないの?とか言ってくる奴のサポートしたくない

nasm使い始めた頃、自動でxdata,pdataを作るマクロ組んだけどクソ面倒だったわ
454デフォルトの名無しさん:2011/08/10(水) 22:14:21.29
.xdata、.pdataはNASMの問題だろ第一インラインasmじゃねーし
455デフォルトの名無しさん:2011/08/10(水) 23:02:18.01
インラインにすると前後のCコードから生成されるアセンブラを整合性が
取れる形にしなきゃいけないからコンパイラを作る上で大きな足枷になる。
それに最近のコンパイラはかなり優秀だし、どうしても使いたいなら
インラインじゃないアセンブラを別途コンパイルしてリンクすればいい。
456デフォルトの名無しさん:2011/08/11(木) 19:05:01.82
そもそも、intrinsic ってすべてのアセンブラ命令に対して用意されてないよね?
インライン廃止して置き換えきくものなの?
457デフォルトの名無しさん:2011/08/11(木) 19:47:16.31
ML64をどうぞ
458,,・´∀`・,,)っ-○○○:2011/08/12(金) 23:32:17.80
Intelコンパイラでは64ビットでも使える
459デフォルトの名無しさん:2011/08/14(日) 22:43:09.11
Intelコンパイラは普通に使えるから問題ないんだけど、
常にIntelコンパイラが使えるとは限らないからねぇ。
今は無理してインラインアセンブラで書かなくとも、
Intrinsicを使ってもそんなにさがない場合が多いし、
汎用性を考えると殆どIntrinsicを使うようになってしもうた。
460,,・´∀`・,,)っ-○○○:2011/08/14(日) 23:23:11.65
YASMでいいやって思うようになった
461デフォルトの名無しさん:2011/09/05(月) 00:49:29.68
4Gamer.net ― 2013年の「Haswell」は,大きな転換点。Ultrabookで「PCの再定義」を狙うIntelはHaswell世代で何をもたらすのか
http://www.4gamer.net/games/132/G013298/20110904002/
462デフォルトの名無しさん:2011/10/06(木) 23:25:02.55
変数一個とSIMD用のレジスタ直接演算できないの?
463,,・´∀`・,,)っ-○○○:2011/10/07(金) 00:53:21.47
不自由でない日本語でおk
464デフォルトの名無しさん:2011/10/07(金) 03:16:05.74
32bitレジスタの内容とxmmレジスタの4領域の内容で四則演算したい。
四則演算が無理でも、xmmレジスタの4領域を一命令で全て同一の値にできたらありがたい。
465デフォルトの名無しさん:2011/10/07(金) 13:23:09.79
それって _mm_set1_epi32() とかじゃダメなわけ?
466デフォルトの名無しさん:2011/10/08(土) 18:10:17.95
>>465
まさしくそれです。
ありがとうございます。
467デフォルトの名無しさん:2011/10/12(水) 20:19:14.24
_mm_set1_epi32ってgccで使ったらめちゃくちゃアホなコード吐いてた記憶がある
468デフォルトの名無しさん:2011/10/12(水) 22:09:21.54
gccがアホなだけでは?
469デフォルトの名無しさん:2011/10/13(木) 19:13:58.46
だからそう言いたいってことだろ
アホか?
470デフォルトの名無しさん:2011/10/14(金) 04:55:59.40
_mm_set1_epi32はアホなコードが吐き出される可能性があるからダメだ、という風にもとれるが。
>>469はちょっと頭が悪すぎるんじゃなかろうか。
471デフォルトの名無しさん:2011/10/14(金) 07:26:01.69
お前がアホだw
472デフォルトの名無しさん:2011/10/14(金) 17:39:34.48
アホなコードが吐き出される可能性があるのはintrinsics全部だろ…
473デフォルトの名無しさん:2011/10/15(土) 06:59:05.70
>>470
アホ
474デフォルトの名無しさん:2011/10/16(日) 21:18:49.05
お前ほどじゃない。
475デフォルトの名無しさん:2011/10/17(月) 16:33:18.43
だれかこれのCore i7で動く高速版頼む。(APIはこのままで)
http://hibari.2ch.net/test/read.cgi/tech/1130349336/649
476デフォルトの名無しさん:2011/10/18(火) 14:55:32.02
コンパイラによる最適化前提で、こんなのとか。
#include <smmintrin.h>
double NormalizeDouble(double value, register int digits){
static double t0[] = {1, 10, 100, 1000, 10000, 100000};
static double t1[] = { 1, 0.1, 0.01, 0.001, 0.0001, 0.00001 };
__m128d xmm0 = _mm_set_sd(value);
__m128d xmm1 = _mm_set_sd(t0[digits]);
__m128d xmm2 = _mm_set_sd(t1[digits]);
xmm0 = _mm_mul_sd(xmm0, xmm1);
xmm0 = _mm_round_pd(xmm0, 0); //ほぼ四捨五入。こまけぇこたぁいいんだよ!
xmm0 = _mm_mul_sd(xmm0, xmm2);
return _mm_cvtsd_f64(xmm0);
}

うん、多分早くなってない。
477デフォルトの名無しさん:2011/10/18(火) 15:38:32.26
>>476
おぉ、サンクス!
3割くらい速くなってるぽい。
478デフォルトの名無しさん:2011/10/18(火) 15:42:51.10
ちなみにg++ -O -msse4.1の結果:

__Z18NormalizeDoubleSSEdi:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
movl 16(%ebp), %eax
movsd 8(%ebp), %xmm0
movsd __ZZ18NormalizeDoubleSSEdiE2t0(,%eax,8), %xmm1
mulsd %xmm1, %xmm0
roundpd $0, %xmm0, %xmm0
movsd __ZZ18NormalizeDoubleSSEdiE2t1(,%eax,8), %xmm1
mulsd %xmm1, %xmm0
movlpd %xmm0, -8(%ebp)
fldl -8(%ebp)
leave
ret
479デフォルトの名無しさん:2011/10/24(月) 17:52:49.41
お、-msseregparmつけたらさらに3割くらい速くなったっぽ。
ググってもこの手の話題出ないね。
480デフォルトの名無しさん:2011/10/24(月) 17:58:57.41
まさかと思うが、-msseregparmで検索してないだろうな。
481デフォルトの名無しさん:2011/10/24(月) 18:05:43.11
したけど何か?
6500件、日本語ページ8件とか。
482デフォルトの名無しさん:2011/10/24(月) 18:27:24.77
先頭にハイフンがついていると否定検索になるって言いたいんじゃないだろか。
483デフォルトの名無しさん:2011/10/24(月) 19:01:28.99
まさか"-"つきで検索できないバカでもないだろうに、なんだろうね。
484デフォルトの名無しさん:2011/10/24(月) 22:26:04.16
メモリ上のテーブル参照するのと、SSE使って逆数求めるのでは、どっちが早いんだろうか?
485デフォルトの名無しさん:2011/10/24(月) 22:26:40.67
だめだ、-msseregparmつけると単体テストじゃ動くのにどっかおかしくなるな...
486デフォルトの名無しさん:2011/10/25(火) 11:43:44.62
名前からするとそのオプションってABIを変更するんじゃないか?
だとしたらリンクする全てのプログラムをそのオプションでリコンパイルしないとダメとか?
487デフォルトの名無しさん:2011/10/25(火) 13:00:24.51
manにはそう書いてあるしもちろんそうしてるがダメなんだよ。
488デフォルトの名無しさん:2011/10/25(火) 17:01:39.57
libcも
489デフォルトの名無しさん:2011/10/25(火) 17:06:04.57
>>488
そうやね、今man読み直して理解した。
attribute()使ってみるわ。
490デフォルトの名無しさん:2011/10/28(金) 22:28:15.77
● -mregparm=num
 regparm属性により,コンパイラは最高でnumberによって指定される個数までの整数引き数を,
スタックではなくEAX,EDX,ECXレジスタに入れて渡すようになります.

  # gcc test238.c -S
  # gcc test238.c -mregparm=3 -S
 スタックで渡す方法で生成されたアセンブラをリスト4に,
レジスタで渡すように生成されたアセンブラを
リスト5に示します.また,元のソースをリスト6に示します.

 引き数がレジスタに渡されていることがわかります.
491デフォルトの名無しさん:2011/10/28(金) 23:41:12.75
/* 質問させて下さい。ゼロかどうかを判断するにはどうすればよいか悩んでいます。
現在は、下のようにプログラムを組んでいますが、特に SSE2 の場合遅いです。
実際のプログラムでは表示ではなく、if 文の条件式の中で使っています。
CPU は Core2Duo E6600 と Core2Quad Q9550 です。どなたか教えてください。*/
#include <smmintrin.h>
#include <stdio.h>
typedef union tagMM { long long i[2]; __m128i m; } mm_t;
const mm_t MM_FULL = {{-1,-1}};

#define IS_ZERO_SSE4(A) (_mm_testz_si128(A,MM_FULL.m)!=0)

int IS_ZERO_SSE2(const __m128i a) {
long long temp[2];
_mm_storeu_si128((__m128i*)temp,a);
return temp[0]==0&&temp[1]==0;
}

int main(void) {
mm_t zero={{0,0}}, test={{0,8}};
printf("zero SSE2:%d SSE4:%d\n",IS_ZERO_SSE2(zero.m),IS_ZERO_SSE4(zero.m));
printf("test SSE2:%d SSE4:%d\n",IS_ZERO_SSE2(test.m),IS_ZERO_SSE4(test.m));
return 0;
}
492デフォルトの名無しさん:2011/10/29(土) 00:12:01.06
なんか知らんがSSEで0比較程度のものをやるだけなら遅くて当然だと思うが
493デフォルトの名無しさん:2011/10/29(土) 01:13:59.60
メンバにm128i_i64を持ってる処理系ならそれ使ったほうが見やすい
494デフォルトの名無しさん:2011/10/29(土) 01:32:17.66
こんなのでいいんじゃね?
int IS_ZERO_SSE2(const __m128i a) {
return _mm_movemask_epi8(_mm_cmpeq_epi8(_mm_setzero_si128(),a)) == 0xffff;
}
495491:2011/10/29(土) 01:44:32.89
>>494
素晴らしい! ありがとう。
これは思いつかなかった。
496 ◆0uxK91AxII :2011/10/29(土) 14:20:36.29
>>491
stackに積んであるのを積み直すとか、アリエナイ。

return 0 == (a.m128i_u32[0]| a.m128i_u32[1]| a.m128i_u32[2]| a.m128i_u32[3]);
497デフォルトの名無しさん:2011/11/02(水) 23:39:21.83
初心者ですがこれ読んどけって書籍ありますか?
あまり情報が無いので
498デフォルトの名無しさん:2011/11/02(水) 23:52:39.89
団子の書き込み
499デフォルトの名無しさん:2011/11/03(木) 00:21:11.16
インテルの資料だけで充分以上に思えるが…
500デフォルトの名無しさん:2011/11/03(木) 01:23:46.20
俺は、
http://sky.geocities.jp/krypton_pl/x86/x86ext.htm
これと、Intelのドキュメントだけでプログラミングしてる。
MASMでゴリゴリ書く派なんだけどね。
どんな命令あるか把握してそれを組み合わせるだけだからな。
501デフォルトの名無しさん:2011/11/03(木) 03:36:10.75
なんか書籍にするようなもんじゃないって気がするな
502デフォルトの名無しさん:2011/11/03(木) 14:00:45.65
Intel C++コンパイラー・ユーザー・リファレンス・ガイドの組み込み関数リファレンス部分にはだいぶお世話になってる。
これと、Intelが配布してるIA-32アーキテクチャマニュアルだけで困ったことは殆ど無い。

組み込み関数使う派だけど、あんまり頭の性能よくないから、アンチョコ無しでは書けないんだよね、俺。
すぐに「SSE2までだとどんな命令あったっけ?」「うろ覚えだけどこんな感じのあったよね?」ってな感じになる。
使ってなんとなく覚える→忘れるを繰り返す感じ。

猿でも使えるSIMDアルゴリズムコピペ事典とか誰か作らないかな。
DVD-ROM付きで、やりたいことを検索すると、サンプルコードとアルゴリズムの解説が出てくるようなやつ。
503デフォルトの名無しさん:2011/11/04(金) 01:19:54.70
>>502
おっ?そんなもの作ってくれるのか
よろしく
504デフォルトの名無しさん:2011/11/04(金) 01:24:46.30
>>502
作ると結構売れると思う
ここは一つ
505デフォルトの名無しさん:2011/11/04(金) 11:12:54.01
ここで作る?
506デフォルトの名無しさん:2011/11/05(土) 18:24:54.55
SSEで投機計算するのに向いてる分野ってある?
507デフォルトの名無しさん:2011/11/05(土) 20:14:26.38
>>506
MPEGのエンコード
508デフォルトの名無しさん:2011/11/05(土) 23:26:42.37
GPGPUが登場して以降、CPUで計算するような分野じゃなくなりつつあるから…>並列処理
ここで話すようなことではないけれど、同様のものならGPU利用のものやシェーダーのそれのほうが
需要が多そうな気もする。
509デフォルトの名無しさん:2011/11/06(日) 04:17:34.93
GPGPU?縛りきつくて使い物にならないからいらね。
510デフォルトの名無しさん:2011/11/06(日) 07:27:30.56
>>502
>組み込み関数使う派だけど、あんまり頭の性能よくないから、アンチョコ無しでは書けないんだよね、俺。 
そんなあなたに
Intel Intrinsic Guide(要JAVA)
ttp://software.intel.com/en-us/avx/
511デフォルトの名無しさん:2011/11/07(月) 01:09:55.84
...なんてこった、日本語がないじゃないか。
512デフォルトの名無しさん:2011/11/07(月) 01:12:12.35
あー、でも検索しやすい。いいねこれ。
ありがとう!
513,,・´∀`・,,)っ-○○○:2011/11/12(土) 14:47:03.59
簡単な関数ならYASMで書いちゃうのも手かな。
OSごとのレジスタ渡しの違い考慮するのがめんどいけど。
514,,・´∀`・,,)っ-○○○:2011/11/12(土) 14:50:12.18
机の横に置くなら本よりもPDFが読めるタブレットだな。
515デフォルトの名無しさん:2011/11/12(土) 17:42:23.15
書き込みできねぇし
それにしても二つのRGB値を混合する命令くらい載せろよ電卓野郎
516デフォルトの名無しさん:2011/11/13(日) 10:57:50.17
ペンタブでpdfに書き込みまくれるようにならんの?
517デフォルトの名無しさん:2011/11/13(日) 18:33:49.43
PCならふつーに出来る。
518,,・´∀`・,,)っ-○○○:2011/11/13(日) 19:52:25.46
GALAPAGOSのXDMF形式なら各ページ200文字程度までメモは残せる。
PC側のクライアントで変換できるんじゃなかったかな。






GALAPAGOSどこにも売ってねえ
519デフォルトの名無しさん:2011/11/25(金) 17:36:44.90
ymmレジスタでメモリコピー書いてみたんだが、速度がSSEとほとんどかわらん。
基本的に同じ程度しかパフォーマンスが出ない認識でおk?
520,,・´∀`・,,)っ-○○○:2011/11/26(土) 00:04:04.31
storeが16バイト/clkなので、単純なメモリコピーじゃ性能出ないよ。
レジスタ上で何かしらオペレーションするコードでないとSSEとの差を出しにくい。
521デフォルトの名無しさん:2011/11/26(土) 00:57:43.23
将来的に速くなることはないかな?
522デフォルトの名無しさん:2011/11/26(土) 02:22:00.87
キャッシュ内ならあるかもね
523デフォルトの名無しさん:2011/11/26(土) 10:48:55.50
HaswellでL1帯域を2倍にするって噂だな

相対的にコストの高い外部メモリ帯域は諦めてでも
チップ内帯域と生FLOPSを上げた方が全体でパフォーマンスを出せる
というのがここしばらくの流れだよね
NECのベクトルスパコンですらB/F比を下げ続けてるから
524デフォルトの名無しさん:2012/01/05(木) 15:25:04.62
冬休みにSandy-EをIYHしたので、浮かれた気分でSSEで書かれた自前のコードをAVXに頑張って書き換えてみた。
2倍まで行かなくてもせめて2割くらいは。。。と思っていたら全く変わらなかった。
アセンブリを見てみると、アライメントがとれているのにvmovupsを使っていたので、
組み込み関数が悪いのかと思い、頑張ってインラインアセンブラで書き換えてみた。
結果は変わらないどころか、少し遅くなってしまった。。。orz
アライメントがとれていれば、vmovupsを使ってもvmovapsをつかっても変わらんのか?
ちなみにインテルコンパイラを使って試した限り。
GCCでは組み込み関数は使えたけど、インラインアセンブラではymmレジスタが使えんかった。

525デフォルトの名無しさん:2012/01/05(木) 15:45:01.46
>アライメントがとれていれば、vmovupsを使ってもvmovapsをつかっても変わらんのか?
変わらない

AVX256化して速くならないとすると
store幅は変わってないとか
insertf128でport5ボトルネックとか
フロントエンドボトルネックでuOPキャッシュに入る程度にループを小さくする必要があるとか

AVX256ってなんかデコーダにペナルティある気がするんだけど気のせい?
526デフォルトの名無しさん:2012/01/05(木) 15:47:39.98
AVXは128bitでもmovapsがいらないからport5が空くのとレイテンシが短くなるのとで速くなることが多いけどね
-xAVXで全く変わらないんであればそもそもなんか別のところがボトルネックな気がする
527デフォルトの名無しさん:2012/01/05(木) 17:22:44.98
現状のAVXは命令数が減ってちょっと速くなる事がある程度。
AVX2が来ないうちは色々楽しめない。来てもたいして速くならないかもしれない。
コア増えてくれたほうが、普通にリニアに速くなってくれる。
528デフォルトの名無しさん:2012/01/05(木) 17:50:07.40
わけでもない。
529,,・´∀`・,,)っ-○○○:2012/01/05(木) 18:05:27.08
単純にメモリネックだったりしない?
530デフォルトの名無しさん:2012/01/05(木) 18:22:32.72
>>527
FPUの演算ボトルネックならSandyBridgeのAVX256bit化で2倍近くになるだろ
GEMMとかね

SandyBridgeのAVXはデータパスは既存を流用して演算器だけの追加だから
Westmereと比較するとかなり少ない追加コスト済んでいる
>AVX2が来ないうちは色々楽しめない。
と言っているようなFMAが有効なプログラムではコア増やすより安上がり
531デフォルトの名無しさん:2012/01/05(木) 18:27:37.50
FMAが有効なような演算ボトルネックのプログラムなら
言葉足らずだったすまん
532,,・´∀`・,,)っ-○○○:2012/01/05(木) 18:45:11.30
現行AVXではシャッフルがあんまり自由利かないからね。
ループの内側でvinsert*/vextractを繰り返してるようならデータ構造そのものを
変える(AoS-SoA変換して)方が効率あがることもあるよ。

メモリにボトルネックはないって自信があるならIACAで静的コード解析してみるのも手だと思うよ。
533デフォルトの名無しさん:2012/01/05(木) 18:51:07.04
AVXはvbroadcastもソースがメモリオペランドに限定されていたり使いにくいよね

IACAはバイパスレイテンシが入ってないとか
あんまり精度の良いツールではないよな
もっとましなパイプラインシミュレータを公開すればいいと思うんだけどね
Intelの開発現場では確実に使っているはずなんだから
534デフォルトの名無しさん:2012/01/06(金) 14:43:14.72
>>524
> GCCでは組み込み関数は使えたけど、インラインアセンブラではymmレジスタが使えんかった。
GCC 4.5.2で出るけど?
__m256 v0, v1, v2;
asm volatile ("vaddps %2, %1, %0\n\t":"=x"(v0):"x"(v1), "x"(v2));
535デフォルトの名無しさん:2012/01/06(金) 18:32:52.42
俺もAVXに対応したけど全く変わらないな
ベクトルのdot演算とかユークリッドノルムとか超基本的な処理なんだが
536デフォルトの名無しさん:2012/01/06(金) 18:35:49.00
だーかーらー
537デフォルトの名無しさん:2012/01/06(金) 18:43:48.72
内積はデータ量も演算量もNに比例するからメモリ帯域ボトルネックだろ
行列積が速くなるのはデータ量はN^2演算量はN^3なのでキャッシュが有効だから
538524:2012/01/07(土) 00:02:40.65
色々と調べてみたら、どうもメモリがボトルネックだったようで、
6スレッドではなく、1スレッドで動かせばAVXを使うと1割くらい早くなった。
でも6スレッド走らせると、SSEより若干遅くなった。

>>534
直接ymm0とか書きこむとエラーはいて止まってしまった。
539534:2012/01/07(土) 14:39:47.14
>>538
手元だと出るけど?
入出力オペランド付けるときは%%ymm0、付けないときは%ymm0とか、そういうのを間違ってる気がする。
540,,・´∀`・,,)っ-○○○:2012/01/07(土) 20:53:53.56
何だ初心者かよ
541デフォルトの名無しさん:2012/01/08(日) 20:42:13.83
>>539
こんな感じでコンパイルかけると、
asm volatile (
"vmovups (%2), %%ymm0\n\t"
"vmovups (%3), %%ymm1\n\t"
"vmovups (%4), %%ymm2\n\t"
処理が続く
)

こんなエラーを吐く。
xxx.cpp:xxx:x:不明なレジスタ名 ‘%ymm1’ が ‘asm’ 内にあります
とかが続く。
xmmは問題なし。

インテルコンパイラだと問題ないからあんまり気にしていない。
ちなみにUbuntu11.10でGCC4.6.1でも4.4.6でもおんなじだった。

>>540
団子さんに比べたら初心者かもね。
542デフォルトの名無しさん:2012/01/08(日) 21:04:08.51
団子さん、Intelに転職してアーキテクトやってくれよ。
543,,・´∀`・,,)っ-○○○:2012/01/08(日) 22:14:25.45
gcc -v
544デフォルトの名無しさん:2012/01/09(月) 02:30:34.43
Ubuntu11.10でgcc4.6.1でも4.4.6でも普通に通るけどな
バージョンはbinutilsの方が重要な気はするけど
545541:2012/01/09(月) 11:04:46.90
>>544
binutilsはbinutils 2.21.53.20110810-0ubuntu5.1。
まあ、自分のシステムが変な設定しているのかも。
レスサンクス。

546デフォルトの名無しさん:2012/01/10(火) 01:14:15.61
>>541
単にAVX用のオプション指定してコンパイルしてないとか?

本当にbinutilsが関係してるのかなぁ…
インラインアセンブラの意味解析をasに丸投げはしてないでしょ。
547デフォルトの名無しさん:2012/01/10(火) 02:21:25.44
__m256な変数とレジスタの対応付けをしなけりゃそのままアセンブリに挿入されるだけだよ
%%ymm20とか存在しないレジスタを含んだコードもコンパイルまでは通るのがその証拠
だからAVXに対応していないバージョンのgccでもインラインアセンブラでAVXを使って
yasmでアセンブルするとかも可能
548デフォルトの名無しさん:2012/01/11(水) 09:26:35.69
MacPortsだったらbinutilsがAVXに対応してないのでclang使え
549デフォルトの名無しさん:2012/01/12(木) 09:02:07.88
>>541
破壊オペランド(asmの最後のオペランド)にymmって書くとそのエラーになるみたい。
ymmのかわりにxmm書いとけば大丈夫な挙動をしてるように見えるが、どうなんだろう…
550デフォルトの名無しさん:2012/01/12(木) 13:47:35.80
バージョンと環境とシンプルな検証コードをコピペするところはじめたら
551デフォルトの名無しさん:2012/01/12(木) 21:44:49.08
>>547
>__m256な変数とレジスタの対応付けをしなけりゃそのままアセンブリに挿入されるだけだよ 
>%%ymm20とか存在しないレジスタを含んだコードもコンパイルまでは通るのがその証拠 
ええ、そうなんだ。知らなかった。
結構いい加減なのね。
552デフォルトの名無しさん:2012/01/13(金) 12:44:54.85
ymm20ワロタ
553,,・´∀`・,,)っ-○○○:2012/01/16(月) 03:19:35.94
どうマッピングされるの?
554デフォルトの名無しさん:2012/03/03(土) 06:02:16.57
Intel Intrinsic GuideがAVX2に対応していた
ttp://software.intel.com/en-us/avx/
555デフォルトの名無しさん:2012/03/04(日) 23:15:32.07
誰か同じ内容の処理をSIMDでやると消費電力が減るとか、電力当たりの処理量が上がるとか、その手の話って知らない?
556デフォルトの名無しさん:2012/03/04(日) 23:35:16.60
GPGPU絡みの論文でも漁ってみたら
557デフォルトの名無しさん:2012/03/04(日) 23:39:13.81
よく知らないけど、さっさと仕事終わらせてHALTかければ時間あたりのWattすうへるんじゃね?
558デフォルトの名無しさん:2012/03/05(月) 00:12:05.05
よく知らないけど命令数減るんだから電力減るんじゃね?
559デフォルトの名無しさん:2012/03/08(木) 02:55:27.17
AVX2でunsignedな比較ぐらい用意しとけよIntel
560,,・´∀`・,,)っ-○○○:2012/03/08(木) 03:03:23.32
Javaにはunsignedなんてないぜ
561デフォルトの名無しさん:2012/03/08(木) 08:42:36.54
たぶんAMDが用意してくれるよ
562デフォルトの名無しさん:2012/03/08(木) 11:51:00.21
またかよ
563デフォルトの名無しさん:2012/05/11(金) 23:53:38.33
ちゃんと__declspec(align(16))を付けているんだけど
__m128メンバが16バイト境界に置かれずアクセス違反で落ちる
生成場所はヒープじゃなくてスタックだし・・
VC++2010EEfだけど打つ手なし?どーすりゃいいんだろ?
564デフォルトの名無しさん:2012/05/12(土) 00:41:45.91
と思ったらヒープだったみたい
お騒がせしたし
565デフォルトの名無しさん:2012/05/12(土) 01:11:01.38
>>563
構造体の宣言と変数の定義両方につけてる?
566デフォルトの名無しさん:2012/05/12(土) 02:43:05.64
>>565
いや、__m128メンバを持つクラスを持つ
もっと底のインスタンスがヒープでした。
そいつは_aligned_mallocで確保してなかった。
つーか対応すんの超面倒
567デフォルトの名無しさん:2012/05/12(土) 12:20:23.46
placement new書けばよろし
てか、__m128は計算時に使うものでメンバに持たないほうがいいのでは
どちらにしろデータのアライメントはいるけども
568デフォルトの名無しさん:2012/05/12(土) 17:41:30.45
operator newはどこまで遡って付ける羽目になるかわからんし
std::vectorにはallocator無しじゃ入れられないし
わかってりゃそもそも使わなかった・・
569デフォルトの名無しさん:2012/05/12(土) 18:42:43.12
32bitを使っていると8バイトでアライメントされるから、
64bit使えばいいんじゃない。
まあ、AVXではおんなじことが起こるけど。
そんときは128bitのOSで・・・・。
570デフォルトの名無しさん:2012/05/13(日) 07:56:14.41
__m65536をアライメントするには一体何ビットのOSが必要なんだ
571 ◆0uxK91AxII :2012/05/13(日) 08:06:47.32
16[bit(s)]で十分。

vectorに突っ込む発想は無かった。
572デフォルトの名無しさん:2012/05/13(日) 08:52:00.94
Ivy BridgeでAVXは拡張されてるのでしょうか?
573 忍法帖【Lv=6,xxxP】 :2012/05/13(日) 13:16:33.11
されません
574デフォルトの名無しさん:2012/05/24(木) 23:41:14.54
やっぱりヒープの_aligned_mallocが納得出来ない。
例えば、以下のクラスがあったとすると、
class A{
char x;
__m128 y;
};
A* a = new A; // NG
A* a = new( _aligned_malloc(16) ) A; // OK
575デフォルトの名無しさん:2012/05/24(木) 23:41:50.10
16byte境界にアラインしなきゃいけないのはAのインスタンスじゃなくて
Aのインスタンスのメンバのyのはずだよね?
なんで、Aをnewするのに16byte境界にそろえなきゃいけないの?
576デフォルトの名無しさん:2012/05/25(金) 01:59:10.69
class A { void *p; } ってあって、4バイトアラインが必要なのはAじゃなくてA::pだよね?
なんでAをnewするのに…っておかしくね?
577デフォルトの名無しさん:2012/05/25(金) 02:51:29.88
if (__alignof(T) > 8) {...

みたいな分岐を見てしまった時の絶望感
578デフォルトの名無しさん:2012/05/25(金) 06:56:01.85
>>574
yを__declspec(align(16))とか__attribute__((aligned(16)))でアライメント指定したうえで
(__m128はそのように定義済み)
A自体も_aligned_mallocしないと
Aの先頭アドレス*A内におけるyの先頭アドレスが16の倍数になる保証がないのでは


579 ◆0uxK91AxII :2012/05/25(金) 07:24:15.51
そういう境界は、コンパイラなりライブラリ内で>>577 みたいにしていて気にしなくても良さそうなものだけど。
580デフォルトの名無しさん:2012/05/25(金) 08:22:42.98
>>574
>>575
基本的にnewはアライメント属性を無視しランタイム固有のアライメントでアドレスを返してくるので使えない。

メンバ変数のアライメントを合わせるには
A *a = new(_aligned_offset_malloc(sizeof(A), 16, offsetof(A, y))) A; // offsetofはmalloc.h
を使うが、

__m128はアライメント属性 __declspec(align(16)) を持っているので
class A {
char x;
char pad[15]; // <--- 変数としては見えないけど存在する
__m128 y;
};
となり、Aのインスタンスの先頭を16バイトアライメントすれば自動的にA::yのアライメントも合う様になっている。

なのでより引数の少ない
A *a = new(_aligned_malloc(sizeof(A), 16)) A;
でOK。
581デフォルトの名無しさん:2012/05/25(金) 19:18:35.73
なんで納得できないのか理解できねーよな
sizeof(A)が動的に変化するとでも思ってんのかねぇ
582デフォルトの名無しさん:2012/05/25(金) 22:44:10.28
メンバーのアライメントの指定がクラス内や構造体内でのアライメントの指定であって
クラスや構造体の先頭アドレスが指定したアライメントの倍数でなければ
メンバのメモリアドレスがアライメントの倍数になるわけではない
ってことが分かってないだけだろ
583デフォルトの名無しさん:2012/05/27(日) 04:11:09.96
構造体のアライメントは正しく16になるけどoperator newが16バイトにアラインしてくれない問題なんだけど、
構造体のアライメントが16にならない問題だと誤解されている気がする。
584デフォルトの名無しさん:2012/05/27(日) 13:06:55.37
VirtualAlloc使えよ
アラインメントがページサイズの4096バイトになるから
585デフォルトの名無しさん:2012/05/27(日) 16:29:51.01
operator newが16バイトにアラインしてくれないなら
構造体のアライメントは正しく16になってないだろ

586デフォルトの名無しさん:2012/05/27(日) 16:47:44.48
生メモリ (N+1)*sizeof(T)バイト取ってstd::alignでも使ってろよ
587デフォルトの名無しさん:2012/05/27(日) 20:23:33.18
>585
__alignof で見てみなって。16になってるから。
VCのoperator newが単にmallocするだけで、mallocが8でしかalignしないのが問題だよ。
> If arg >= 8, alignment will be 8 byte aligned. If arg < 8, alignment will be the first power of 2 less than arg.
588デフォルトの名無しさん:2012/05/28(月) 15:46:50.32
どうもクラスでアライメントって抵抗あるなあ。
どうしても構造体にしてしまうわ。
589デフォルトの名無しさん:2012/05/28(月) 18:20:18.41
構造体にしてクラスメンバに持たせたら同じことが起こる
590デフォルトの名無しさん:2012/06/01(金) 18:55:24.99
class A{
char x;
__m128 y;
public:
void *operator new(size_t size) {return _aligned_malloc(size, 16);}
void *operator new[](size_t size) {return _aligned_malloc(size, 16);}
void operator delete(void *p) {_aligned_free(p);}
void operator delete[](void *p) {_aligned_free(p);}
};
591デフォルトの名無しさん:2012/06/02(土) 09:18:59.89
_mm_mallocの方が移植性高いぞ
592デフォルトの名無しさん:2012/06/02(土) 10:42:28.75
>>591
_mm_mallocはでかい領域のメモリ確保に失敗することがあるから、
newで作れるならnewの方がいい。
確保の速度を気にしないのなら自分でアロケータを作るのがいいと思うが。

593デフォルトの名無しさん:2012/06/02(土) 13:03:57.68
なんか知らんが、適当に確保したあとアライメントと調整するのが普通だろ。
594デフォルトの名無しさん:2012/06/02(土) 13:24:09.97
まともなOSならposix_memalign()使えるから。
595デフォルトの名無しさん:2012/06/02(土) 16:42:18.03
>>594
Windowsはまともじゃないんだな。
Linuxではposix_memalign()でも数十GBのメモリ確保は出来なかったな。
OSのメモリ管理によるのだろうけど。
596 ◆0uxK91AxII :2012/06/02(土) 16:54:04.64
昔書いたaligned_mallocを見たら、size+alignのoverflowを考慮していなかった。
/(^o^)\
597デフォルトの名無しさん:2012/06/02(土) 17:21:41.96
>>595
今時posixも満足にサポートしないのはまともなOSじゃないでしょ。
OSXではposix_memalign()で100TBとか普通に確保できる。実メモリは当然mapされてないけど。
あとOSXやiOSのmalloc()/newはちゃんと16 byte alignされた領域を返す。
598デフォルトの名無しさん:2012/06/02(土) 20:26:22.45
posix信者キモい
599デフォルトの名無しさん:2012/06/02(土) 20:42:39.61
僕のちん○もposix準拠です
600デフォルトの名無しさん:2012/06/02(土) 21:00:57.82
>>597
Linuxだと、_mm_mallocやposix_memalign()だと、大体搭載メモリの半分ぐらいで確保を諦めたみたいでエラーで落ちていたな。デバッグがかなり大変だった記憶しか無い。今は知らいないが。

> 今時posixも満足にサポートしないのはまともなOSじゃないでしょ。
> OSXではposix_memalign()で100TBとか普通に確保できる。実メモリは当然mapされてないけど。
確保されてねーじゃんwww。
601デフォルトの名無しさん:2012/06/02(土) 21:28:29.53
>>600
>確保されてねーじゃんwww。
仮想記憶下のメモリアロケーションとはそういう物だよ。
実メモリがmapされるのは確保したページに最初に触った時。
ファイルをmmapした時も同様、触った所だけメモリ上に現れる。
602デフォルトの名無しさん:2012/06/02(土) 23:12:54.83
>>601
ん?>>601のPCに100TBのストレージがあるとは思えないし、100TBは仮想メモリのどこに確保されたの?
アクセスの途中でエラーにでもなるのか?
603デフォルトの名無しさん:2012/06/02(土) 23:51:49.26
手抜きなOSはアクセスされて初めて実メモリを確保する。
Linuxのmanpageにも "This is a really bad bug." って書いてあるし、POSIX以前にCとしておかしい。
604デフォルトの名無しさん:2012/06/03(日) 08:07:45.14
オーバーコミットも知らないアホがいんのかよ
605デフォルトの名無しさん:2012/06/03(日) 10:01:38.71
OOM Killer先輩オッスオッス
606デフォルトの名無しさん:2012/06/03(日) 10:05:37.70
>>603
Linuxもdemand paging使ってるから、触ったら実メモリ確保だよ。
アドレス空間確保と実メモリ確保の関係解ってない奴は仮想記憶の
基礎から学んでくれ。
607デフォルトの名無しさん:2012/06/03(日) 12:43:21.33
>>603
おまえ…恥さらすなよw
608 ◆0uxK91AxII :2012/06/03(日) 23:28:03.57
急に例外が来たので。
609デフォルトの名無しさん:2012/06/03(日) 23:53:47.93
メモリがwrittenになることはできませんでした!
610デフォルトの名無しさん:2012/06/05(火) 14:50:01.55
linux64bit, java7u4(32bit), jni(gcc4.6 -m32)で、javaからsseは有用かどうかベンチマークなどを作りながら数日調査してるんですが、sseの成績はまったくかんばしくありません。
少なくともループでA[k]+=B[k]やA[k]=A[k]*B[k]+C[k]など単純なものはsseはjava forloopの2倍以上遅くなります。(2000回ループなどではsseが2,3倍速いときもあります。)

jniのスタックコールが足を引っ張るのは分かるのですが、それがsseが歌うfloatを4つ一度にopするので高速を打ち消すほどでなんですか?
MAC(FMA)はsse1,sse2にないのでaddps,mulpsで作ってますが、基本的にfloat,intしか興味ないのでapiとしてはsse1の範囲です。
611デフォルトの名無しさん:2012/06/05(火) 15:35:34.67
float4の演算4回よりメモリアクセスの方が遙かにコスト高くね?
612デフォルトの名無しさん:2012/06/05(火) 15:50:34.24
Javaはよく知らんが、floatとdoubleの変換は発生してたりしないよね。
どの途、4倍にはならないと思う。3倍行ってりゃ御の字じゃね?
613デフォルトの名無しさん:2012/06/05(火) 16:07:40.28
jvmに限らず、asm,c99などネイティブオブジェクト生成環境以外からsseをコールするとなると関数呼び出し呼び戻しのスタックコールのコストが問題になるので、vmからsseは有用か否かの問題java(jni)だけの問題じゃないと思うんですけど。
たとえばjvmに限らず、rubyなどscript vmや、browser組み込みのjs runtimeもsseはまったく使えないということです。
OpenCL, Open64, OpenMPの方でやろうと思うのですが、sse,avxはx86ネイティブ環境以外もうオワコンなんですか?
614デフォルトの名無しさん:2012/06/05(火) 16:11:07.67
よく知らんけどループごとCで書けば関数呼び出しは1回で済むんじゃないの
615デフォルトの名無しさん:2012/06/05(火) 16:12:13.40
使い方間違ってるのにオワコンとか言われてもお前ん中ではそうなんだろとしか言いようないわ
616デフォルトの名無しさん:2012/06/05(火) 16:32:13.28
間違ってるかどうかこれだけの情報ではわからんよ
ちょっとググってみてもJNIのコストは非常に大きいという愚痴が多数見つかるからな
ま、Javaがオワコンということでここはひとつ
617デフォルトの名無しさん:2012/06/05(火) 16:43:41.93
vmやnative環境に関係なく、ベンチ作ってテストをしていて気がついたんですけど、
floatが4程度だと配列添字のアドレッシング計算のためにx[offset+k+3]でsseの一度に4つ演算は相殺になりませんか?
for (k=0; k<N; k+=4) {
float a[]={x[k],x[k+1],x[k+2],x[k+3]}
float b[]={y[k],y[k+1],y[k+2],y[k+3]}
v4sf ssea=__builtin_load(a), sseb=__builtin_load(a);
ssea=__builtin_add(ssea, sseb);
__builtin_store(ret,ssea);
}
単純なコードはこのようなものですが、add(ssea,sseb)を計算するために、offset+k+3 などをメモリスタックx,yからsseレジスタへ転送するために8回+しているので、sse_addの効果がまったくなくなるようです。
またmovups(x+offset+k)だとしても、sse_addを使えば4回の + が一回で済むように見えますが、実際は x+offset+k, y+offset+k でvoid* typeの + を2回してるので、これも(メモリアクセス遅延の問題以外に)sseが永遠に越えられない壁として問題あるように思います。

メモリアクセスについては、movntps, movaps (loadaps)などアラインメントに神経質になってもそれに見合う性能向上はまったくないのでmovupsしか興味ありません。
618デフォルトの名無しさん:2012/06/05(火) 17:21:56.95
なんでスタックにコピーしてるの?
619デフォルトの名無しさん:2012/06/05(火) 17:25:51.75
for (k=0; k<LENGTH; k+=4) {
float arra[]={x[offset+k],x[offset+k+1],x[offset+k+2],x[offset+k+3]};
float arrb[]={y[offset+k],y[offset+k+1],y[offset+k+2],y[offset+k+3]};
v4sf ssea=__builtin_load(arra), sseb=__builtin_load(arra);
ssea=__builtin_add(ssea, sseb);
__builtin_store(ret+offset+k,ssea);
}
620デフォルトの名無しさん:2012/06/05(火) 17:38:59.50
for (k=0; k<LENGTH; k+=4) {
float arra[]={x[offset+k],x[offset+k+1],x[offset+k+2],x[offset+k+3]};
float arrb[]={y[offset+k],y[offset+k+1],y[offset+k+2],y[offset+k+3]};
v4sf ssea=__builtin_load(arra);
v4sf sseb=__builtin_load(arrb);
ssea=__builtin_add(ssea, sseb);
__builtin_store(ret+offset+k,ssea);
}

for (k=0; k<LENGTH; k+=4) {
v4sf ssea=__builtin_load(x+offset+k);
v4sf sseb=__builtin_load(y+offset+k);
ssea=__builtin_add(ssea, sseb);
__builtin_store(ret+offset+k,ssea);
}

float[]で受けるかv4sfで直接初期化するは、本質的に有意な差はありません(多分)。
それよりもv4sf ssea[], *ssebなどのようなデータのブロックについて、 ret+offset+k などでアドレッシングを求めるために + が数回必要なのはsse apiをいくら拡張しても回避できません。
sse,avxはアラインメントも含めて非常に神経質であり、あまり深入りしてもsse,avx設計思想ではx86上のvm(java, dotnet, js, scriptlang)ですら性能向上は全くなく、
時間を使ってsse,avxを勉強してもそれに見合うプログラムの性能向上もないのでほかのストリーミング演算開発環境を検証します。
621デフォルトの名無しさん:2012/06/05(火) 17:39:17.76
あー、どうしようもなく間違ってたな
多分君は生粋のJAVAerで、ポインタを知らないんだよね
622デフォルトの名無しさん:2012/06/05(火) 17:52:36.99
java使ってる時点で速度云々言うのはおかしいと思う
623デフォルトの名無しさん:2012/06/05(火) 18:17:03.18
俺もそう思う
624デフォルトの名無しさん:2012/06/05(火) 18:33:59.20
4 floatのときはsseの性能向上はもとの[]ループのコードと比べて、a,b,retのために3回整数アドレス計算する必要があるから4/3=1.33 倍 (3/4 * 100%)が限界なんだろうな。
625 ◆0uxK91AxII :2012/06/05(火) 19:05:12.69
>float a[]={x[k],x[k+1],x[k+2],x[k+3]}
これはひどい。
626デフォルトの名無しさん:2012/06/05(火) 19:38:05.94
x,y,retがfloat*なら

x+= offset;
y+= offset;
ret += offset;
for (k=0; k<LENGTH; k+=4, x+=4,y+=4,ret+=4) {
v4sf ssea=__builtin_load(x);
v4sf sseb=__builtin_load(y);
ssea=__builtin_add(ssea, sseb);
__builtin_store(ret,ssea);
}

でいいだろ
627デフォルトの名無しさん:2012/06/05(火) 19:45:15.42
もしあなたが速度狂・最適化狂を自称するなら、ポインタ変数は変更不能の方がいいですよ
例えば float *const, float *restrict など
628デフォルトの名無しさん:2012/06/06(水) 05:46:51.35
>>627
もしあなたが速度狂・最適化狂を自称するなら
比較コード書いてベンチマークで示してみ
できないから
629デフォルトの名無しさん:2012/06/06(水) 08:34:56.65
>>620
なんかうまく言えないが、ひどいコードだな。
630デフォルトの名無しさん:2012/06/06(水) 11:19:34.82
>>628
何がどうできない?
もしあなたが(ry
ちゃんと説明くらい書かんと。
631デフォルトの名無しさん:2012/06/06(水) 11:27:09.37
A V X ってなんかエロいな・・・
632デフォルトの名無しさん:2012/06/06(水) 12:06:29.86
>>631
AVがAudio&VisualではなくAdultVideoだと思う口かw
633デフォルトの名無しさん:2012/06/06(水) 12:07:19.95
>>632
あの呼称、やめてほしいよね。
「趣味はAVです」って言えないw
634デフォルトの名無しさん:2012/06/06(水) 13:58:38.73
ピュアヲタなんて恥ずかしいもんな
635デフォルトの名無しさん:2012/06/06(水) 22:30:20.43
Javaスレじゃないから多くは書かないが、
Javaから大きい配列をMappedByteBuufer 以外の方法でJNI+C/C++に渡してたりしないか?
だったら遅くなるだろうし。
そもそも、JNI+C/C++側で「なにもせずに」値を返すだけのプログラムを書いてもJNIのせいで
遅かったりしないか?
(だったら、SSE/AVXはおろか、OpenCL/CUDA/DirectCompute も当然遅いわけだが)
636デフォルトの名無しさん:2012/06/07(木) 15:41:59.99
どうしてMappedByteBuuferなんですか?
637デフォルトの名無しさん:2012/07/17(火) 23:19:17.58
新命令 ADCX, ADOX, RDSEEDと3DNowのPREFETCHWをサポート(pdf注意)
http://software.intel.com/file/45088

PREFETCHWの機能判定のフラグはAMDと同じものを使う
ただし、AMDはPREFETCHとPREFETCHWの両方のサポートを意味するが
IntelではPREFETCHWのみのサポートを意味するようだ

上記マニュアルより
> CPUID.(EAX=8000_0001H):ECX[bit 8]=1 indicates PREFETCHW is supported.

http://support.amd.com/us/Embedded_TechDocs/25481.pdf
> 3DNowPrefetch: PREFETCH and PREFETCHW instruction support
638,,・´∀`・,,)っ-○○○:2012/07/29(日) 15:04:14.80
PREFETCHはキャッシュレベル指定できる別命令があるから要らないでしょ
だが正直今更だな
639デフォルトの名無しさん:2012/09/21(金) 01:05:42.45
なんか忘れ去られたスレだな。

とりあえず、__m128とか__m256になってもいまだにシフトをleftとかrightとかで呼んでんじゃねーよ。
頭ん中じゃハイアドレスが右だからわかりにくいんだよ。
640デフォルトの名無しさん:2012/09/21(金) 03:25:21.45
VEX encodedな命令はm128とかm256をオペランドに取れる演算命令で
メモリのアラインメントを気にしなくて良くなったことに今更気付いた

AMDはK10あたりで独自拡張してたようだが
641デフォルトの名無しさん:2012/09/21(金) 09:49:34.17
SSE2やAVXって
倍精度使えるようになっても
除算や平方根の精度って11bitのまま?

やっぱり倍精度なんだから5xbitまで、精度を求めるべき?
またそれは現実的に可能か?
642,,・´∀`・,,)っ-○○○:2012/09/21(金) 11:37:46.39
rsqrt*/rcp*のことならもともと単精度しかサポートしてない


倍精度で使える命令はdiv*やsqrt*で、こっちはもともと有効桁53ビットまで求められる。
643デフォルトの名無しさん:2012/09/21(金) 21:26:18.56
ymmレジスタの上位もしくは下位128bitのみを32bit単位で即値でシャッフルできる命令はないのかね
644デフォルトの名無しさん:2012/09/24(月) 20:51:01.41
AVX になっても、結局使うデータ型は、 int 8bit * 16 と float 32bit *4 だけじゃね?
645デフォルトの名無しさん:2012/09/24(月) 21:05:07.88
m256は使えたら使うだろ。AVX2じゃないといまいち使いづらい気はするが。
646デフォルトの名無しさん:2012/09/24(月) 22:14:18.95
cross lane shuffleはレイテンシ3ってのが微妙
647デフォルトの名無しさん:2012/09/25(火) 09:28:35.03
未来予測して先に結果返せというのか。
648デフォルトの名無しさん:2012/09/26(水) 20:13:51.38
>>640
AVX使えるマシンが無いからわからないけど、VC2010EEで/arch:AVX使ってコンパイルした場合
_mm_load_si128がvmovdqa、_mm_loadu_si128がvmovdquで、ストアもvmovdqaとvmovdquが
使い分けられていたけど、VEX付いてる時はCore系のloaddquみたいに内部的には同じ命令に
なっててloaduでもアライメントが揃ってたら高速で実行可能なのかな?
649デフォルトの名無しさん:2012/09/27(木) 04:02:36.36
いやmov*ps,movdq*に関してはAVXでも区別されてるよ
ロード/ストアするサイズでアラインメントが揃ってないと例外が発生する

まあ全てにmovups,movdquを使っていてもアラインメントが揃っていれば速度低下はない
という意味ではAVXが実行できるCPUでは全てそういう実装になっているだろうけど
650648:2012/09/27(木) 22:12:28.64
>>649
>まあ全てにmovups,movdquを使っていてもアラインメントが揃っていれば速度低下はない
後でhttp://users.atw.hu/instlatx64/を見てみたら、movdqaとmovdquのload、storeのペアが
同じ速さになっていたからmovdquメインでも問題なさそうだとは思ったけど、
やはり速度低下せずに利用可能ですか。これは助かるなぁ。

651デフォルトの名無しさん:2012/09/28(金) 00:04:34.76
速度低下が無いならアライメント命令の存在意義は…
652デフォルトの名無しさん:2012/09/28(金) 17:16:59.20
Nehalem以降等ペナルティが無い実装なら存在意義はない
AtomやCore2等ペナルティがある実装なら意義はある
653デフォルトの名無しさん:2012/09/28(金) 23:35:32.58
Visual Studio 2008でintrinsics使ってるけど、/Og(自動レジスタ割り当てその他)を
付けたときだけ正しく動作しないようになってしまった…。
こういう場合どのへんを疑えばいいかな?デバッガが使えないからどう攻めればいいか
見当がつかない。
ためしにループ内でメモリに書き出す部分の前や後ろにmfence入れてみたら、今度は
プログラム自体が落ちちゃうし。
SSE4.1のコード生成の問題に対するHotfixがあったんで当ててみたけど現象は変わらず。
654,,・´∀`・,,)っ-○○○:2012/09/29(土) 04:36:38.92
一応アラインメント揃ってればキャッシュライン境界をまたぐことはないから
明示的にアラインメント命令を使う意義は無くもない
655デフォルトの名無しさん:2012/09/29(土) 15:50:43.77
それはアラインメントを揃える意義があるかどうかという話であって
movaps/movdqaの意義があるかという話ではないと思うが
656デフォルトの名無しさん:2012/09/29(土) 16:09:28.58
はぁ?
657デフォルトの名無しさん:2012/09/29(土) 17:00:56.88
いや最近のCPUではmovups/movdquを使って
アラインメントが揃った領域にアクセスしてもペナルティがないから
movaps/movdqaの意義って何なのって話でしょ元々は>>651
658デフォルトの名無しさん:2012/09/29(土) 17:06:22.14
消費電力とか…?
659デフォルトの名無しさん:2012/09/29(土) 17:36:54.04
単に互換性の問題だろ
660デフォルトの名無しさん:2012/09/29(土) 17:42:52.31
>>653
VS2012でも使えば?
2008世代はMASMに関してはコード生成のバグはかなりあった。
661 ◆AxwOEvsrgEGX :2012/09/29(土) 18:19:49.27
>>653
おまじないでも書けばいいと思うよ。
#pragma optimize("g", off)
662デフォルトの名無しさん:2012/09/29(土) 19:22:00.38
>>660
実行順序が変わることで顕在化するバグパターンでもあるかと思ったけど、
やっぱり環境の問題なのかな。
なるべく新しいバージョンでやりたいのはのはやまやまだけど、今回は環境が
VS2008に限定されているんで。

>>661
それがonのときに発生する問題を解決したいわけで。
663デフォルトの名無しさん:2012/09/29(土) 20:21:57.47
>>662
Microsoftに言って対応してもらう以外ないだろ
664デフォルトの名無しさん:2012/09/29(土) 21:11:16.29
最適化有効にすると落ちるから1日ソース調べまわったが見つからず、
結局OCが原因でしたって経験はあるw
設定時負荷テストはしてたから疑ってなかった。
665デフォルトの名無しさん:2012/09/29(土) 21:51:28.99
>>663
つまり?最適化オプションの有無で動作が変わるとしたら
ほぼコンパイラの問題と考えてよいということか。
666,,・´∀`・,,)っ-○○○:2012/09/29(土) 22:06:25.22
>>655
スケジューラの都合もあるでしょ。
dqu/upsだと境界をまたぐ可能性があるが、アラインメントがとれてるかどうかは
実際はアドレスを解決するまではわからない。
スケジューリング段階でアラインメントとれてることがわかればRAWハザードの影響を
軽減できる(かもしれない)

>>658
そんなのもあるかもね
667デフォルトの名無しさん:2012/09/29(土) 22:07:33.14
最適化で動かなくなるケースのほとんどがソースのバグだけどな
668デフォルトの名無しさん:2012/09/29(土) 22:09:09.54
おっとVC++2003をdisるのはそこまでだ
669デフォルトの名無しさん:2012/09/29(土) 22:27:22.41
>>666
memory disambiguationで投機実行されるからRAWハザードは影響ないと思うなあ
670デフォルトの名無しさん:2012/09/29(土) 23:03:05.74
>>667
興味深い。SSEで発生するケースにはどんなものがある?
671,,・´∀`・,,)っ-○○○:2012/09/30(日) 00:17:31.16
>>669
普通アラインメントのとれたロードのほうがレイテンシも短くて済むし
スケジューラの都合的に有利なのは間違いなさげだけどね

それこそ実装依存な気もするが
672デフォルトの名無しさん:2012/09/30(日) 00:32:38.53
>>671
もちろん全ての実装で等速なわけではないので
アラインメントが揃ってるのが分かってる場合は
aps/dqaを明示的に使ったほうがいいというのには同意する
673,,・´∀`・,,)っ-○○○:2012/09/30(日) 04:12:11.11
とりあえずmovdqaをmovdquに置換してみて遅くならないことを検証してみればいいのかな
674デフォルトの名無しさん:2012/09/30(日) 13:00:08.39
/Og の使用は推奨されてないといっても聞く気はなさそうだが。
モノみないとなんともだが、最小コード書いて動くかどうか見て、それの積み重ねしないとハマるだろ
675デフォルトの名無しさん:2012/09/30(日) 13:50:37.64
そりゃ/Ogオプションそのものの話。
Releseビルドのデフォルトに指定されてる/O2は/Og/Os/Oy/Ob2/Gs/GF/Gyと等価。
676デフォルトの名無しさん:2012/09/30(日) 14:21:26.34
Core 2以前では、movdquはアライメントの制約が無い代わりにアライメントが揃っていても速度の低下があったから
movdqaが用意された訳でしょ。

単体で完結してるアプリならアライメントのコントロールも可能だけど、
ライブラリやコーデックみたいなプログラムだと入力、出力共にアライメントが揃ってるとは限らない上、
独立してずれがあったりするんだよね。

ベクタ長が長くなるだけでも端数処理のために似たようなコードを繰り返し書かなきゃいけないけど、
さらにアライメントを揃えるとなるとmovdqaを使うコードの前にも端数処理コードが必要になるうえに、
それでも入出力の片方のアライメントしか揃えられないことが多い。

概ねアライメントが揃っててデータの個数がベクタ長の倍数になってることが多くても、
保証されていなければmovdqu使って速度低下を容認することが多かったし、
コンパイラでもAVXならメモリオペランド使ってレジスタを節約したりしてるから
アライメントの制約の無い命令が常に速度低下しなくなるメリットは大きいよ。
677,,・´∀`・,,)っ-○○○:2012/09/30(日) 17:03:14.98
ワーク領域(ヒープ)までアラインメント揃えずに使っていいかっていうとそれは違うよねって話にはなる
678デフォルトの名無しさん:2012/09/30(日) 21:13:41.25
SSE とか、結局 8bit int と 32bit float しか使わないよな。
679,,・´∀`・,,)っ-○○○:2012/10/01(月) 02:31:58.32
普通に倍精度使うけど?

整数は16ビットが一番使うような(8bit intってようは1バイト文字だろ)
680デフォルトの名無しさん:2012/10/01(月) 04:33:37.64
よほど速度稼ぐという理由が無いかぎり使わないよ。
基本、int32とdoubleで済ます。
681デフォルトの名無しさん:2012/10/01(月) 07:55:17.08
単精度使いまくるよ
桁落ちにびくびくしながらだけど
682デフォルトの名無しさん:2012/10/01(月) 16:44:17.64
x87を使いたくないだけなんです
683デフォルトの名無しさん:2012/10/01(月) 19:02:46.03
処理時間に制限があるプログラムばかり書いているから
単精度でSIMDとOpenMP使う以外ありえないだろって考えになってるな

684デフォルトの名無しさん:2012/10/02(火) 00:21:28.65
GPU使えよ
685デフォルトの名無しさん:2012/10/02(火) 08:42:25.76
GPU使ってるしGPUも単精度のほうが速いから
CPUのコードも自然と単精度で統一される
686デフォルトの名無しさん:2012/10/02(火) 09:56:52.29
単精度で総和取るときとかどうしてる?
この点thrustはいいね
687デフォルトの名無しさん:2012/10/02(火) 13:23:04.76
並列化するとプロセッサの数で総和が変わったりもあるからあまり気にしてないな
金の計算ではないし
誤差に影響を受けにくい手法が使えるから速度を優先できる
688デフォルトの名無しさん:2012/10/02(火) 13:35:58.14
>>685
Sandy-Eが出てからは、GPUに大きなアドバンテージが無くなった。
GPUは補助的に使うようになった。
次はkeplerだろうけど、スペックみたらXeon Phiの方が速そうだし、楽に今までのコードが動かせそうだ。これはかなり重要だしな。
Cell、cudaとやった経験から、やっぱり過去の遺産(技術)は大事だなあと実感する。
689デフォルトの名無しさん:2012/10/02(火) 13:45:29.06
GPUなら1万円で1TFLOPSが手に入るのに。
690デフォルトの名無しさん:2012/10/02(火) 17:27:52.61
CUDAはプログラミングが面倒だからできれば使いたくない
データ転送が遅いから使いどころも難しいし
CPUにはがんばってほしい
691デフォルトの名無しさん:2012/10/03(水) 18:29:24.22
そこでCPUでもGPUでも計算させれるOpenCLじゃないのか?
同時には無理だったと思うけど。
692デフォルトの名無しさん:2012/10/03(水) 20:24:55.60
>>691
OpenCLで書いたプログラムは
CPUだとAVX+OpenMPで書いたものより遅く
GPUだとCUDAで書いたものより遅い

速度を優先するならハードウェア向けに書いたほうがいいし
速度を優先しないならC言語でいいだろって思ってる
OpenCLのコンパイラがハードウェアの専門知識を持って
ガチガチに最適化してくれればいいのだろうが
それができるほど抽象的に書けないし
693デフォルトの名無しさん:2012/10/03(水) 22:52:36.66
速いとか遅いとかは、どこかの結果を盲信してないで、自分でベンチを作って自分でやらないと自分が進むべき道を失いますよ。
694デフォルトの名無しさん:2012/10/03(水) 23:52:42.09
おまえ以外はみんなやってるよ
695デフォルトの名無しさん:2012/10/04(木) 02:57:06.44
だぁらそれはベンダーに依存するっしょって話で、
NVidiaだとCUDAの方が速いだろうが、AMD(ATI)とかだと分からんよね(漏れは試してない)。
みんなNVidiaとAMD両方で検証してるんか、すごいな。
696デフォルトの名無しさん:2012/10/04(木) 04:07:51.68
>>695
当たり前だろ
697デフォルトの名無しさん:2012/10/04(木) 06:02:56.75
ここまで来ると嘘くせー
698デフォルトの名無しさん:2012/10/04(木) 06:11:10.65
>>697
当たり前だろ
699デフォルトの名無しさん:2012/10/04(木) 08:23:32.79
>>695
ATIなんか普通は使わねーよ。
gpgpuていったらnvidia一択だろうが。
700デフォルトの名無しさん:2012/10/04(木) 08:25:58.81
nvidiaはsse,avxやx86命令セットをサポートしないんですか?
701デフォルトの名無しさん:2012/10/04(木) 08:29:42.65
複雑すぎてプログラミングできんわ
702デフォルトの名無しさん:2012/10/04(木) 11:43:40.39
NVIDAのGPUでスパコン作った話は山ほどあるけど
ATIのGPUを使った話は聞いたことない
あの研究者たちはベンチマークしなかったからNVIDAを選んだのかw

まあ暗号の総当りなんかはATIのほうがコスパよくて人気らしいが
703デフォルトの名無しさん:2012/10/04(木) 11:45:02.08
NVIDIAな
704デフォルトの名無しさん:2012/10/04(木) 11:51:20.73
コスっぱ?
705デフォルトの名無しさん:2012/10/04(木) 16:05:01.36
コストパフォーマンスな
706デフォルトの名無しさん:2012/10/04(木) 16:17:40.96
それはCPU(Opteron)とかの話で、GPUじゃないんでは?
ブルになると浮動小数点系は2コアに1ユニットだから、Intelの方がコスパいいかもしれない
AVXとかSSEも2コアに対して1ユニットなんかね
707デフォルトの名無しさん:2012/10/04(木) 23:12:01.07
AMD/ATIは非Windows方面のドライバがな
NVIDIAのプロプライエタリドライバの方がサポートがましだから
708デフォルトの名無しさん:2012/10/04(木) 23:29:40.10
709デフォルトの名無しさん:2012/10/05(金) 01:16:36.30
>>702
長崎大のゲフェスパコン作った先生がそのあとCaymanクラスタ作っとるよ
ゴードン・ベル賞とったのはこっちだったはず
n-bodyとか総当りの多体計算だとピークFLOPSで勝るラデのほうが使いやすくパフォーマンスが出るみたいな論文も書いてた
710デフォルトの名無しさん:2012/10/05(金) 01:20:50.14
711デフォルトの名無しさん:2012/10/05(金) 12:41:12.48
並列化の粒度が細かければSPが多いRADEONのほうが速いのだろうな
712デフォルトの名無しさん:2012/10/05(金) 15:38:25.88
>>709
あれはコスパ賞だろう
特別賞とったTUBAME2.0はTeslaクラスタだ

713デフォルトの名無しさん:2012/10/05(金) 15:52:47.17
ラデの事例ないのかっていうから出ただけだろう
ピークパフォーマンスで受賞したTUBAME2.0と
価格あたりFlopsのコストパフォーマンス賞撮ったDEGIMAクラスタくらべること自体ナンセンスだとおもう
714デフォルトの名無しさん:2012/10/07(日) 14:14:41.69
VisualC++だが、アライメント指定した変数をstd::transform()とかに突っ込むと
// error C2719: '_Func': __declspec(align('16')) の仮引数は配置されません。
みたいなエラーが出るけど、これは関数が値型で引数を取ってる為だよね。
どう解決すべき?標準C++ライブラリを改変するのは気が引けるのだが。
715デフォルトの名無しさん:2012/10/07(日) 14:25:04.89
>>714
単にテンプレートの展開でVC++が__declspec(align('16'))何かを理解できないからかね?
ポインタで渡してあげるようにすればできると思う。

716デフォルトの名無しさん:2012/10/07(日) 14:38:55.65
>>715
std::accumulate()も同様でわかりやすいから例に挙げるが

Ty accumulate(_InIt _First, _InIt _Last, _Ty _Val)

この_Valが値渡しの為に、引数はアライメント出来ないという制約とバッティングしてしまう。

Ty accumulate(_InIt _First, _InIt _Last, const _Ty& _Val)

こうすれば通るんだけど、ライブラリ側直すのやだなって。
717716:2012/10/07(日) 14:45:53.94
こういうのもそうだけど、
CPUってSIMD使って、カタログスペック底上げするんなら
もうちょっと開発言語とすりあわせてもいいんじゃねーかなと思う。

うちのCPUは1Tflopsですよー
でも.NETやJavaはダメでーす
C++は使えるけどSTLはダメでーす
Cは使えるけどfloatもdoubleはダメでーす
って実質使えねーのと一緒じゃねーか。
718デフォルトの名無しさん:2012/10/07(日) 14:51:13.36
まぁハード屋ってのは今も昔もそういうもんだなw
719デフォルトの名無しさん:2012/10/07(日) 18:31:14.04
>>716
これは無理だわ。

stlは多々でさえ並列化が不十分な上、ハードウェアに依存するsimdはなおさらだな。

ただ、stlでもvectorとかであれば、インテルコンパイラなら自動ベクトル化してくるけど。
720デフォルトの名無しさん:2012/10/08(月) 17:50:50.85
vc2008 だと問題なく値渡しするようだ。
でも元々アドレスで渡したいんだからポインタを渡せばいいんじゃないだろうか。

> もうちょっと開発言語とすりあわせてもいいんじゃねーかなと思う。
それは C/C++ の規格に言うことじゃないな。そして CPU ベンダーじゃない Microsoft に言うことでもない。
ベンダーの都合で言語の仕様を変えていくと(ライブラリだけど)DirectX8/9 のようなカオスになる。
C/C++ は抽象度が低すぎるせいでうまく融合させられないが、言語にサポートを求めるなら Fortran とか使うと少し幸せになるんじゃなかろうか。

独自拡張の話をすると、vector というキーワードを取り入れているコンパイラがある。
PS3 に搭載された Cell 向けに IBM が実装して、vector char とか vector float のように型宣言できて、レジスタ渡しできたりする。
intrinsics とあわせると、まあ捨てたものじゃないくらいにはなってると思う。
また、arm neon 向けの開発環境だと、int8x8_t とか float4x4_t とか(大元の宣言は __attribute__だけど)、同様に使える拡張があったりする。
SIMD 対応に関しては Cg とか GLSL と比べるとまだまだ足りないけど、ある程度以上を求めるなら、互換を考えると別の言語を作るしかないんじゃなかろうか。
721デフォルトの名無しさん:2012/10/08(月) 17:59:27.92
くだらんこと妄想してないで素直にインテルコンパイラ使え
722デフォルトの名無しさん:2012/10/11(木) 00:25:28.80
個人や大学の研究に使うんだったらインテルコンパイラはフルバージョンで無料だから使わない手はないな。
仕事でやるなら。。。。少々高いけど、付属のライブらいが再配布可能だからまあよし。

もっともコテコテにインラインASMや組み込み関数を使うならあまり効果はないけどな。
あとBoostやらQtやらのライブラリを使う時は多少面倒かもしれん。
723デフォルトの名無しさん:2012/10/11(木) 01:19:15.05
>>722
非商用版はLinux用しかないけど、Parallel Studio XE 2013まであるのか…
724デフォルトの名無しさん:2012/10/26(金) 19:49:21.27
今更Ivyを入手したのでzero latency register moveを検証してみた。
クロック計測スレが落ちてたのでこっちに書くけど微妙にスレ違いですまん。

どうも計測してみると、デコード後にmovと後続の依存するuopを
ひとつのuopに結合するような挙動をしているように見える。
・uop fusionのようにデコーダ自体がfused uopを吐くわけではない(これはx86命令として分かれているので当然)
・macro fusionのようにデコード前に結合してひとつのuopを吐くわけでもない(x86命令として連続していなくても結合される)
・zeroing idiomのようにそれ単体でuopが消滅するわけでもない(依存関係の全く発生しないmovを並べても消滅しない)
loop:
movaps xmm1, xmm0
movaps xmm0, xmm1
dec ecx
jnz loop
これだとSandyは3clk/loop,Ivyは2clk/loop
loop:
movaps xmm1, xmm0
movaps xmm2, xmm1
movaps xmm0, xmm2
dec ecx
jnz loop
これだとSandyは4clk/loop,Ivyは3clk/loop
loop:
movaps xmm1, xmm0
movaps xmm2, xmm1
movaps xmm3, xmm2
movaps xmm0, xmm3
dec ecx
jnz loop
これだとSandyは5clk/loop,Ivyは3.33clk/loop <-3clk/loopで回らないのは何故?

ともかくBulldozerの実装とはちょっと違うようだ。
725,,・´∀`・,,)っ-○○○:2012/10/26(金) 20:22:41.26
ああ、意図がようやくわかった。

movapsもdec+jccもPort5で実行されてて、Ivy Bridgeはmov*の除去が行われるから
2個のmovapsあたり1サイクルで処理できるはずってことね。

1個目は
0: movaps xmm1, xmm0 +movaps xmm0, xmm1
1: dec ecx + jnz loop
で2サイクルで処理できるわけだ(実際に処理されるのは後続分)

2個目は多分こう
0: movaps xmm1, xmm0 + movaps xmm2, xmm1
1: movaps xmm0, xmm2
2: dec ecx + jnz loop


問題は3つ目だよね。
0: movaps xmm1, xmm0 + movaps xmm2, xmm1
1: movaps xmm3, xmm2 + movaps xmm0, xmm3
2: dec ecx + jnz loop

で3サイクルで回りそうなのにそうなっていないと。
(なぜか4サイクルかかってる場合がある?)

レジスタファイルのR/Wポートすうの制限ではなさそうさし、
条件をもう少し変えてみたらわかるかも。
726,,・´∀`・,,)っ-○○○:2012/10/26(金) 20:44:32.71
俺はIvy Bridgeのmov除去の仕組みってRenamerでxmm0とxmm1が同じ物理レジスタファイルの
エントリを指すように読み替えてるものだと思ってた(Bulldozerって基本的にこの方式だよね)

文字通り「融合」してるのだとしたら、xmm0の中身をxmm1とxmm2に同時にコピーする
オペレーションに置き換えていることになる。
これもありえない話でもないか。

どういう実装になってるのかわかるとボトルネックも突き止めやすいのだけどね。
727デフォルトの名無しさん:2012/10/26(金) 21:23:33.17
企業秘密です
728デフォルトの名無しさん:2012/10/26(金) 23:21:05.19
>>725-726
そういうことです。少なくともリネーミングで除去しているような挙動ではない。
3つめはループの3回に1回4clkかかっている計算。

こんなコードならどうよ、という提案があれば回してみるよ。
729デフォルトの名無しさん:2012/10/27(土) 02:03:35.51
結合はサイクルあたり一つしかできないと仮定すれば
4つのmovapsがちょうど4つ組に入ったとき (この確率は1/3だ)、他より1クロック長くなるだろう
730デフォルトの名無しさん:2012/11/18(日) 16:42:26.60
http://pr.fujitsu.com/jp/news/2012/11/13.html

Xeon Phiの15000 x 15000 の行列積が5.3倍って、
どうおもう?
そこらへんのGPUでも5倍ぐらいいくと思うんだが・・
731デフォルトの名無しさん:2012/11/18(日) 17:04:11.21
どうも何もx86ベースメニーコアで(何とか)GPGPUと同等まで
持って来ましたドヤァっていうもんじゃないの
732デフォルトの名無しさん:2012/11/18(日) 17:49:13.34
やけに遅いな
チューニングができてないんかな?
733,,・´∀`・,,)っ-○○○:2012/11/18(日) 19:11:28.55
>>732
Phiのコアは1コア当たり2命令/clkで、うちベクトル命令(単純なストアを除く)は1命令だけしか発行できない。
たとえばL1からレジスタへのLoadだけでもベクタ側のパイプを使う。
x86らしくLoad+FMAの融合演算で性能を稼ぐアプローチ。
むしろこの構造で実効8割以上もっていけるだけでも富士通すげーや。

Fermiは16SPに対して8DPだから実効性能比が悪かった。
Kepler2は、24SPのSMXごとに8DPと命令帯域あたりの理論FLOPSをFermiの2/3に落としたから
そら実効値上がるわな。
(もちろんSGEMMの実効性能比は悪いまま)


つか行列積程度の単純な問題ならいまどきのGPGPUでボトルネック生じないでしょ。
むしろそれ以外が重要なわけで。
x86コアにベクトルユニットが乗っかった構造のメリットは、GPUではできないような
複雑な分岐を含むプログラムが書けることだ。
ビッグデータ寄りのサーバサイドプログラミング、たとえばパケットフィルタとかにも使えないかと思ってる
734デフォルトの名無しさん:2012/11/18(日) 22:32:18.96
パケットフィルタみたいなものはFPGAでやってるだろうし
その領域は無理だろ
735,,・´∀`・,,)っ-○○○:2012/11/18(日) 23:32:17.47
ポイントはフルプログラマブルであるということ。

たとえば随時新しいウイルスパターンを更新していくことができる。
ウイルスチェックってN×Mの二次元パターンマッチだからメニーコア向けなんだよね
736デフォルトの名無しさん:2012/11/18(日) 23:34:03.80
いろいろ制限多いほうが燃えるくせに。
737,,・´∀`・,,)っ-○○○:2012/11/18(日) 23:38:20.71
Larrabeeの命令セット仕様が出たときからFPよりも整数演算性能に着目してたよ
738デフォルトの名無しさん:2012/11/19(月) 14:10:38.41
>>736
ww
739デフォルトの名無しさん:2012/12/02(日) 13:30:26.40
epi16をps*2に変換する際以下のような手順でやっていますが、
SSE4までの範囲でもっと単純な方法ってありますか?

__m128i ival;
__m128i ival0, ival1;
__m128 fval0, fval1;

ival0 = _mm_unpacklo_epi16( ival, _mm_setzero_si128() );
ival0 = _mm_srai_epi32( ival0, 16 );
fval0 = _mm_cvtepi32_ps( ival0 );
// fval1も同様
740デフォルトの名無しさん:2012/12/02(日) 14:54:17.17
_mm_cvtepi16_epi32 あたり?

とりあえず、最低限ドキュメント読もう。
741デフォルトの名無しさん:2012/12/02(日) 16:00:47.29
ありがとうございます。
つい最近までSSE3縛りでやっていたんですっかり頭の中から除外されてました。

ところで、どういう命令があるか調べるのにまとまったドキュメントか本ってないですかね?
Intrinsics Guideしか持っていないんですが、これだと欲しい命令の目星をつけないと
調べようがないので。
742デフォルトの名無しさん:2012/12/02(日) 17:48:32.85
VSのヘルプ
Intelのドキュメント

MASM派の俺は、
http://sky.geocities.jp/krypton_pl/x86/x86ext.htm

細かい仕様はやっぱIntelのでチェック
743デフォルトの名無しさん:2012/12/02(日) 21:30:07.81
744デフォルトの名無しさん:2012/12/04(火) 01:55:31.30
SEXプロレスリング
745デフォルトの名無しさん:2013/04/08(月) 23:02:57.00
チラ裏
フィルタ演算みたいにロード側のデータ多くてストアが少ない処理は
ストアのアライメントを合わせてalignrでロードを減らすと効果あるよ。
746デフォルトの名無しさん:2013/04/08(月) 23:05:53.21
alignr
こんな命令あったっけ??
747デフォルトの名無しさん:2013/04/09(火) 01:06:17.59
>>746
palignr(_mm_alignr_epi8)だった。shrdのxmm版みたいな命令でSSSE3から使えるよ。
748デフォルトの名無しさん:2013/04/09(火) 19:40:17.21
>>747
ありがとう。

http://msdn.microsoft.com/ja-jp/library/vstudio/bb514041.aspx

う〜ん、いまいち使い方が分からんが、
>>745のような場面では有用なのか。
749デフォルトの名無しさん:2013/04/10(水) 18:42:39.88
たぶん4バイトずつずらしながら16バイトロードを繰り返す…みたいな処理だとpalignrが有効、と言いたいのでは?
750デフォルトの名無しさん:2013/04/10(水) 18:46:19.07
しかし非VEXなpalignrの上位側の16バイトを上書き、という仕様は
下位側ほうが良かったと思う場面にばかり遭遇しているのだが
751デフォルトの名無しさん:2013/06/05(水) 18:07:53.31
Haswellの話題は無いの?
752デフォルトの名無しさん:2013/06/05(水) 18:26:50.05
おれもおもた
753デフォルトの名無しさん:2013/06/05(水) 19:30:58.08
最適化マニュアルはHaswell対応にアップデートされてたが
IACAはまだだな
754デフォルトの名無しさん:2013/06/05(水) 20:29:33.30
やっぱ蓮のAVX2やFMAはつおいのかな?
755デフォルトの名無しさん:2013/06/06(木) 17:54:10.29
Haswellの実測のレイテンシ/スループットが掲載された
http://instlatx64.atw.hu/

4ALU化したものの、4ALU全てに発行できる命令はあまり多くない?
mov, movsx, movzx, not, negあたりは4ポート発行できているように見えるが
mov系は除去が効いてる可能性もある
port0,1の混雑を緩和するのが主な目的かな

シフト量が即値じゃないシフト/ローテート命令が1クロックで実行不可に
スループットも2サイクルになってる理由がよく分からん

整数シャッフルユニットが128bit*2portの構成から256bit*1portになった弊害か
pshuf*/punpck*/pinsr*/phadd*あたりのスループットが低下

pmulld/round*は2ups化のため? 速度半減

SSE2->AVX2でレイテンシやスループットが悪化する命令は少ないが
pmovsx*/pmovzx*/即値じゃないシフト等はレイテンシが2倍

なんか既存コードの実行には不利になっている変更が多い気がするのだが
それでも5%程度はIPCが上がるというのはキャッシュ周りの改善が大きいのだろうか
756デフォルトの名無しさん:2013/06/06(木) 22:30:47.01
>シフト量が即値じゃないシフト/ローテート命令が1クロックで実行不可に
>スループットも2サイクルになってる理由がよく分からん

BMI2のSHLX/SARX/SHRXは2命令同時実行可能でレイテンシ1という謎仕様
757デフォルトの名無しさん:2013/06/06(木) 22:41:20.71
なんかの布石なのかねえ
758デフォルトの名無しさん:2013/06/07(金) 00:40:07.90
>>755
>シフト量が即値じゃないシフト/ローテート命令が1クロックで実行不可に
Sandyでも遅いよ
759デフォルトの名無しさん:2013/06/07(金) 03:16:29.19
Sandyは2-2だったが、Ivyでは1-1に高速化された
Haswellで2-2に戻ってしまった
760デフォルトの名無しさん:2013/06/07(金) 03:18:39.10
あばちゃー
761デフォルトの名無しさん:2013/06/07(金) 04:21:56.59
Nehalemまでは即値もclも変わらなかったはずだが
SandyでPRFベースに変えて8bitレジスタの扱いが難儀になったのかね
762,,・´∀`・,,)っ-○○○:2013/07/06(土) 00:37:53.86
327 X86 :IMUL r16, r16 L: 0.88ns= 3.0c T: 0.29ns= 1.00c
328 X86 :IMUL r32, r32 L: 0.88ns= 3.0c T: 0.29ns= 1.00c
330 X86 :IMUL r16, r16, imm8 L: 1.18ns= 4.0c T: 0.29ns= 1.00c
331 X86 :IMUL r32, r32, imm8 L: 0.88ns= 3.0c T: 0.29ns= 1.00c
333 X86 :IMUL r16, r16, imm16 L: 1.18ns= 4.0c T: 0.96ns= 3.25c←
334 X86 :IMUL r32, r32, imm32 L: 0.88ns= 3.0c T: 0.29ns= 1.00c

前世代からだけど、imm16がついてる命令が軒並み遅いのは解せないね。
なんのためのμOPsキャッシュだよっていう・・・
763デフォルトの名無しさん:2013/07/12(金) 21:59:32.72
>>755
4ALU化かと思ってたら1ユニットはArithmeticじゃないのね
論理演算も、Zero Idiom的なケースで実行回避されてるものは速くなってるが
64bitが遅めだから4ユニットで演算してるのかよく分からないな

GPR使う命令は2OPだからmov系だけでもIPCは向上するってことかな

クロック上がってないのを考慮すると多少退化してるね。
次で本気出すつもりだったプレスコみたいな位置づけかね?
764デフォルトの名無しさん:2013/07/12(金) 23:32:23.87
Haswellで改善してる例

ivy
LOCK ADD [m32], r32 L: 6.28ns= 22.0c T: 7.14ns= 25.00c
MULSS xmm, xmm L: 1.43ns= 5.0c T: 0.29ns= 1.00c
PCLMULQDQ xmm, xmm, imm8 L: 3.88ns= 13.6c T: 2.19ns= 7.67c
VMOVAPS ymm, [m256] L: [memory dep.] T: 0.29ns= 1.00c
VMOVUPS ymm, [m256 + 4] L: [memory dep.] T: 1.67ns= 5.83c
VMULPD ymm, ymm, ymm L: 1.43ns= 5.0c T: 0.29ns= 1.00c
VBROADCASTSS ymm, m32 L: [memory dep.] T: 0.29ns= 1.00c
765デフォルトの名無しさん:2013/07/12(金) 23:35:02.88
haswell
LOCK ADD [m32], r32 L: 5.59ns= 19.0c T: 6.77ns= 23.00c
MULSS xmm, xmm L: 1.47ns= 5.0c T: 0.15ns= 0.50c
PCLMULQDQ xmm, xmm, imm8 L: 2.06ns= 7.0c T: 0.59ns= 2.00c
VMOVAPS ymm, [m256] L: [memory dep.] T: 0.15ns= 0.50c
VMOVUPS ymm, [m256 + 4] L: [memory dep.] T: 0.66ns= 2.25c
VMULPD ymm, ymm, ymm L: 1.47ns= 5.0c T: 0.18ns= 0.63c
VBROADCASTSS ymm, m32 L: [memory dep.] T: 0.15ns= 0.50c
766デフォルトの名無しさん:2013/07/16(火) 23:47:59.50
>>763
デコード側の制限じゃないの?
Pen4も実行ユニットは0.25出るものが、スループット0.33だったりするし
767デフォルトの名無しさん:2013/07/17(水) 00:20:02.49
もしかして たぶん   どうせ   どうやら   やっぱり   また      逝ってよし
オレゴン  オレゴン  オレゴン  オレゴン   オレゴン   オレゴンか  オレゴン
 ┝━━━━┿━━━━┿━━━━┿━━━━┿━━━━┿━━━━━┥
                      88彡ミ8。   /)
                     8ノ/ノ^^ヾ8。( i )))
                      |(| ∩ ∩|| / /   <マダココ!
                     从ゝ__▽_.从 /
                      /||_、_|| /
                     / (___)
                    \(ミl_,_(
                      /.  _ \
                    /_ /  \ _.〉
                  / /   / /
                  (二/     (二)
768デフォルトの名無しさん:2013/07/17(水) 00:27:03.14
>>763
どうせagerが出すInstruction tablesはADD SUB 0.25とか書くだろ
あれはパイプラインとかデコーダの制限は考慮しないからな
769デフォルトの名無しさん:2013/07/20(土) 02:22:13.60
>>766
アホか
普通のALU命令も4並列デコードできなかったらCore2より劣化してるだろ
770,,・´∀`・,,)っ-○○○:2013/07/20(土) 11:16:17.16
デコーダのスループットによる制限は今の命令帯域ベンチに現れないんじゃね?
μOPs cacheだし
771デフォルトの名無しさん:2013/07/20(土) 17:10:15.05
早くこっちに戻れよみんな待ってんぞ
http://anago.2ch.net/test/read.cgi/jisaku/1372163372/
772デフォルトの名無しさん:2013/07/20(土) 19:12:52.47
>>769
あの測定値によってALU側に制限があると考えるおまえがアホ
773デフォルトの名無しさん:2013/07/20(土) 19:47:14.42
>>772
別にALUに制限があるとは言ってねーよ
デコーダに制限があると考えるのがアホだと言っただけだ
そもそもあの手の計測ならuops cacheから供給してるだろうしなおさら引っかからん
774,,・´∀`・,,)っ-○○○:2013/07/21(日) 02:02:18.91
追加のALUポートはJccとかの従来port5で発行していた一部の命令を
オフロードするためのものじゃないかな。
最大命令発行数を増やすことよりポート競合によるパフォーマンス低下を防ぐことに
主眼がおかれてるように思える。

後藤はんが解説してるけど、HaswellのRSは60エントリだそうな。
これは普通に考えれば6エントリ×10段分しかない。

つまり、Sandy Bridgeと比べてRSの段数は増えたが1段あたりのエントリ数は
増えてないことになる。

http://pc.watch.impress.co.jp/docs/column/kaigai/20130602_601851.html

おそらく1クロック毎に供給できる6μOPsのうちの3μOPsはLoad/Store絡みで
ALUにコンスタントに供給できるのは3オペレーションまでなんだろう。
775デフォルトの名無しさん:2013/07/21(日) 02:07:32.05
uops cacheから供給してるなんて保証がどこにあるんだ?

> 2 X86 : 2x 0x66 NOP L: [no true dep.] T: 0.07ns= 0.25c
> 3 X86 : 3x 0x66 NOP L: [no true dep.] T: 0.07ns= 0.25c
> 4 X86 : 4x 0x66 NOP L: [no true dep.] T: 0.09ns= 0.30c
> 5 X86 : 5x 0x66 NOP L: [no true dep.] T: 0.11ns= 0.37c

この結果を見ると、uops cacheから外れていてデコーダの16bytes/cycle制限に引っかかってるようにしか見えないが。
776,,・´∀`・,,)っ-○○○:2013/07/21(日) 02:27:07.48
レジスタ間オペレーションなら1命令5バイトしかないFMA3もスループット0.63cになってるから
正確な数字が出てるともいいがたい。μOPs cacheミスヒットでは説明がつかない事象だ。
本来0.5cだよな。
(まさか8バイトcycleじゃないだろ?)


まあ、FMAに関してはxmm版はBulldozer/Piledriverも0.63cなんだが。
777デフォルトの名無しさん:2013/07/21(日) 04:05:36.74
>>775
で、add reg, regみたいな命令でどうやって制限に引っかかるの?
そもそも16B/clkはL1Iの制限だがな
778デフォルトの名無しさん:2013/07/21(日) 04:42:13.55
http://news.mynavi.jp/special/2013/haswell2/001.html
ここのRMMAの結果を見ると、
uOP CacheにヒットすればIPC=4で実行できている命令でも、
uOP Cacheから外れるとIPC=3に落ちてしまうものが多いのが分かる。
779デフォルトの名無しさん:2013/07/21(日) 16:09:58.57
簡単に0.25出てるなら売れ行きが鈍いとか問題にならないでしょ
バックエンドのどこかの制限で0.25が出ないのに加算器だけ4つ積んだって無駄と言えなくもない
レジスタ増えてuOPキャッシュでデコーダの制限も緩和されてるのにIPCが増えないのは何か制限があると思うな
ポート6以外はSIMDでも使うから256bit演算のディスパッチに失敗するペナルティは大きいのではないか?
それを回避するためのGPmovのバイパスという設計なんかね?

>>775
ALUとuOPキャッシュのベンチ結果が混ざった状態にするかね?
780デフォルトの名無しさん:2013/07/21(日) 19:20:35.97
>>778
この結果を見ればデコーダーの制限と見るのが自然だな。
コンプレックスデコーダを使うまでもない、単純命令はシンプルデコーダーオンリーで処理されるから3命令デコード止まりだというのが大原氏の考えらしいが、
俺もそう思うし、それを匂わすことが最適化マニュアルにも書いてあるよな

>>779
俺はデコーダーの制限をHaswellで取っ払うと思っていたら、そのままなので、Intelはよほどコンプレックスデコーダーを動かしたくないんだなw
781デフォルトの名無しさん:2013/07/21(日) 20:31:01.80
>>780
> それを匂わすことが最適化マニュアルにも書いてあるよな

それってどの記述?
782デフォルトの名無しさん:2013/07/21(日) 22:36:12.14
>>780
uOPキャッシュの利点はPen4みたいにデコーダ1つでもまともに動くってところなんだから
デコーダの制限が結果に現れてるならPen4のスループットが高すぎるよ
783デフォルトの名無しさん:2013/07/21(日) 23:00:34.03
>>782
問題点は何かというと、
>>755の計測結果が1ループ何命令(計何バイト)で計測してるのかが分からないということ。
Pen4のトレースキャッシュは12kuOPsで、HaswellのuOPキャッシュは1.5kuOPs。
仮に1ループ2000命令で計測していたとすれば、
Pen4ならトレースキャッシュにヒットしまくり、HaswellだとuOPキャッシュミス多発という事になる。
784デフォルトの名無しさん:2013/07/21(日) 23:29:32.55
>>783
確かにそうなんだけど、Pen4のuOPキャッシュの容量は
>TC can hold up to 12-Kbyte μops and can deliver up to three μops per cycle.
Kbyteで換算してるんで、そこまで大きくなかったと思う
サイズ自体は同等だったような
>>778のグラフ14でデコード帯域8*4byteになってるからALUはちゃんと搭載されてるみたいだね
となると、リネームかレジスタファイルのアクセスがボトルネックになってるのかも
785デフォルトの名無しさん:2013/07/21(日) 23:40:19.37
公式マニュアルのトレースキャッシュのサイズ表記まちがえてるだろ、これ。
古いCPUだから中の人間違えたか。
786デフォルトの名無しさん:2013/07/21(日) 23:42:04.62
今の最適化マニュアルのその記述は誤植。もともとの正しい記述はこれ。

> In the Pentium 4 processor implementation, the TC can hold up to 12K μops and can
> deliver up to three μops per cycle.
787デフォルトの名無しさん:2013/07/21(日) 23:53:52.37
Haswellの4ALU化はuOPキャッシュにヒットした時の効果だけを狙ったものだろうな
>>775の結果はuOPキャッシュの効果が見えてないけど、それなりに4ALUの意味はあるじゃないの
788,,・´∀`・,,)っ-○○○:2013/07/22(月) 00:41:48.66
Pentium 4の実行トレースは12kμOPs = 128KB(Prescottの場合)
1μOP=1バイトなわけねーしwww
789デフォルトの名無しさん:2013/07/22(月) 01:40:34.44
>>781
こんな記述がある
3.4.2.1 マイクロフュージョン向けの最適化

インテル® Core™ マイクロアーキテクチャーおよびインテル® マイクロ
アーキテクチャー Sandy Bridge では、2 マイクロオペレーション(μOP)からなるフロー
をデコーダー0 から供給する。2 マイクロオペレーション(μOP)のフローをアライメン
トの合ったデコーダーからデコーダー0に移さなければならないので、デコード帯域幅の
わずかな損失が生じる。

あたかも初めからシンプルデコーダーのみを動かしている前提の話だよな
790デフォルトの名無しさん:2013/07/22(月) 03:09:58.64
いやそれは複数uopに分解される命令はcomplex decoderでしか処理できないという話だろ
complex decoderで1uop命令も処理できないとC2DでもNehalemでも4uop/clk出る根拠にならんぞ
791デフォルトの名無しさん:2013/07/22(月) 03:14:04.91
マニュアルより
>There are four decoding units that decode instruction into micro-ops.
>The first can decode all IA-32 and Intel 64 instructions up to four micro-ops in size.
>The remaining three decoding units handle single- micro-op instructions.
>All four decoding units support the common cases of single micro-op flows
>including micro-fusion and macro-fusion.
792デフォルトの名無しさん:2013/07/22(月) 08:33:28.58
つーか、このスレにいながら、>>791程度のことも
みんな把握してなかったんだなw
そのスレの住人はみんなほんとにアセンプリで最適化したコードとか書いているのか?
793デフォルトの名無しさん:2013/07/22(月) 09:39:05.43
>>791は当然知っているものと思っているが。
complex decoderではシングルμOPの命令もデコードする能力があるが、
あえて休ませているというのが>>780の主張じゃなかったのか?
794デフォルトの名無しさん:2013/07/22(月) 13:27:06.41
いやだから
110 X86 :SUB r32, r32 L: 0.07ns= 0.3c T: 0.07ns= 0.25c
111 AMD64 :SUB r64, r64 L: 0.07ns= 0.3c T: 0.07ns= 0.25c
114 X86 :SUB r1_32, r2_32 L: 0.29ns= 1.0c T: 0.09ns= 0.31c
115 AMD64 :SUB r1_64, r2_64 L: 0.29ns= 1.0c T: 0.10ns= 0.33c
154 X86 :XOR r32, r32 L: 0.07ns= 0.3c T: 0.07ns= 0.25c
155 AMD64 :XOR r64, r64 L: 0.07ns= 0.3c T: 0.07ns= 0.25c
158 X86 :XOR r1_32, r2_32 L: 0.29ns= 1.0c T: 0.08ns= 0.28c
159 AMD64 :XOR r1_64, r2_64 L: 0.29ns= 1.0c T: 0.09ns= 0.31c
この結果を見る限り、zeroing idiomsが適用される限り4uop/clkで動いてるんだから
仮にこの結果がuop cacheにヒットしないコードサイズで測ったものだとしてもcomplex decoderも仕事してるのは明らかなんだよ
zeroing idiomsが効かなくなるとスループットが落ちるということは、リネーム以降で何らかのボトルネックがあるとしか読めない
795デフォルトの名無しさん:2013/07/22(月) 15:08:58.60
>>789
マイクロフュージョンが実装される前は「わずかな損失」でもなかったよ
SSEの初期はaddpsとmulpsがユニットが分かれてるのに交互に命令が実行されるような
スループットしか出なかった
addssが倍のスループットになってるからpsはuOP2つ発行してたんだろうな

>>794
3ALUになった時もレジスタの同時使用数制限の話はあったからね
uOPキャッシュでREXの影響も軽減されてるはずだからデコーダの問題とは思えないな
796デフォルトの名無しさん:2013/07/22(月) 18:45:23.96
例えばこの結果 http://users.atw.hu/instlatx64/GenuineIntel00306C3_Haswell_InstLatX86.txt

138 X86 :AND r32, r32 L: 0.29ns= 1.0c T: 0.10ns= 0.33c
146 X86 :OR r32, r32 L: 0.29ns= 1.0c T: 0.07ns= 0.25c

AND r32,r32 だとリネーム以降で何らかのボトルネックがあり、
OR r32,r32 だとリネーム以降にボトルネックがないということ?
それっておかしくない?
797デフォルトの名無しさん:2013/07/22(月) 19:00:23.26
150 X86 :OR r1_32, r2_32 L: 0.29ns= 1.0c T: 0.08ns= 0.28c

orはdependency breaking idioms的な何かが入ってるのかもよ
798デフォルトの名無しさん:2013/07/22(月) 19:15:32.62
この計測プログラムのソースを見ない限りは
これ以上議論しても無駄だね。変則的な結果が多すぎる。
799デフォルトの名無しさん:2013/07/22(月) 19:19:25.23
QueryPerformanceCounterとかで計測してるんだけど、
計測結果の変動幅がすごく・・・大きいです・・・で困ってる。
あれって他のタスクとかで割り込まれてるからなんかな?
計測対象のプログラムが動いてるスレッドだけで浪費したクロック数を出せたらもっと安定するだろうに。

QueryPerformanceCounter自体も最近じゃCPUのクロック数じゃなくて、
マザボのカウンタ使ってて、本当にCPUがどれだけのサイクル喰ったか分かんねーし。
800デフォルトの名無しさん:2013/07/22(月) 19:27:59.81
rdtscで測ってるけどturbo boostに注意すべきという点以外は別に不安定な結果は出ないよ
Windowsでどうだかは知らんけど
801デフォルトの名無しさん:2013/07/22(月) 20:06:29.34
freeのunixで、kernelの中で割り込み禁止して測ればいい
802デフォルトの名無しさん:2013/07/24(水) 13:13:53.54
AVX-512 instructions | Intel Developer Zone
http://software.intel.com/en-us/blogs/2013/07/10/avx-512-instructions
803デフォルトの名無しさん:2013/07/24(水) 17:23:55.82
えっ?!次世代来ちゃうの?
804デフォルトの名無しさん:2013/07/24(水) 17:27:42.33
x,y,zときたら1024bitのレジスタはなんという名前になるのでしょう
805デフォルトの名無しさん:2013/07/24(水) 20:14:55.41
うひょ〜、512bitマンセー♪
806デフォルトの名無しさん:2013/07/25(木) 06:29:03.11
Xeon Phiに512bitのAVXあったやろ
807デフォルトの名無しさん:2013/07/25(木) 19:09:59.43
一般人が気軽に買えるところに降りてくるのが素晴らしいんだよ。
808デフォルトの名無しさん:2013/07/25(木) 19:27:49.64
少なくとも14nmの世代で一般に降りてくる可能性は低そう
809デフォルトの名無しさん:2013/07/25(木) 19:32:58.25
1024bitSIMDハァハァ・・・
810デフォルトの名無しさん:2013/07/26(金) 17:34:45.24
x64の呼び出し規約ではxmm6からxmm15は不揮発性になってるけど、
vzeroupperした後で上位128bitを戻したらまたAVXステートになっちゃうから
ymm6やzmm6とかに関しては揮発性ってことでいいのかな?
811デフォルトの名無しさん:2013/07/27(土) 00:21:47.02
Windowsでは下位128bitだけnon-volatile
行き当たりばったりのクソ仕様
812デフォルトの名無しさん:2013/07/27(土) 01:52:20.27
>>811
>下位128bitだけnon-volatile
後からAVXが登場したとはいえ、行き当たりばったりな仕様ですか。
AVX用にコンパイルすると、スタックのアライメントも32バイトに調節してて、
フレームポインタも必要になってしまうのね。
813デフォルトの名無しさん:2013/07/27(土) 02:00:59.40
スタックのアライメント調節されるのは__m256や__m256iをローカルに確保している場合で、
xmmだけならやらないようですな。
814デフォルトの名無しさん:2013/07/27(土) 03:01:42.04
Haswellで以下の命令シーケンスが2 clockで実行できたからIPC4でてるね。
cmp rax, r12
cmp rbx, r13
cmp rsi, r14
cmp rdi, r15
cmp r8, r12
cmp r9, r13
cmp r10, r14
cmp r11, r15

>>755の結果とは直接関係ないけど、下の情報ではAllocation Queueの部分が4 Fused uOPsになってた。
http://pc.watch.impress.co.jp/img/pcw/docs/601/851/html/17.jpg.html
815デフォルトの名無しさん:2013/07/27(土) 03:02:57.09
ということで、これもIPC4
vpaddq ymm0, ymm8, ymm14
vpaddq ymm1, ymm9, ymmword ptr [rbp]
vpsrlq ymm2, ymm10, 1
add rsi, rax

これもIPC4
add rax, r12
add rbx, [mem1]
add rdx, r13
add rdi, [mem2]

でもこれはIPC3近くまで落ちてしまう。
add rax, r12
add rbx, [mem1]
add rdx, r13
add rdi, [rbp]

これもIPC3程度になる
vpaddq ymm0, ymm8, ymmword ptr [mem1]
vpaddq ymm1, ymm9, ymmword ptr [mem2]
vpsrlq ymm2, ymm10, 1
add rsi, rax

バックエンドにも多少制限がありそうだけど原因は不明。
816デフォルトの名無しさん:2013/07/27(土) 06:33:18.84
[memX]ってなんのアドレッシングモードなの?
初心者ですまん。
817デフォルトの名無しさん:2013/07/27(土) 07:34:32.58
>>816
MASM64でコードセグメント内の定数のアドレスを指定した状態です。

_TEXT64 segment page 'CODE'

 align 64
mem1 qword 0h, 0h
mem2 qword 0h, 0h
818デフォルトの名無しさん:2013/07/27(土) 07:56:48.29
>>814の図はSandyBridgeでした
Haswellの図は
http://pc.watch.impress.co.jp/img/pcw/docs/601/851/html/16.jpg.html
819デフォルトの名無しさん:2013/07/27(土) 09:39:34.77
mem1,mem2はそれぞれ16バイトの0で、
ymmword ptr [mem1]とymmword ptr [mem2]はそれぞれ32バイトの読み込み
ということは、読み込み領域が重なっているということ?
820デフォルトの名無しさん:2013/07/27(土) 11:51:32.58
>>816
たぶんRIP相対アドレッシングって名前
821デフォルトの名無しさん:2013/07/27(土) 13:54:56.12
AGUからは遅延なしでパイパスうけられるけど、
レジスタ直接アドレスだとAGU使わないから、Load Bufferかなにかからアドレス値よむから遅延とか?
んなわけないか。
・レジスタファイル
・リタイアメント
・フォワーディング
のいずれかではあろうが。
822デフォルトの名無しさん:2013/07/27(土) 14:00:01.12
でも、本当にRIP相対ならレジスタよまないからレジスタのポート関係かなあ。
823デフォルトの名無しさん:2013/07/27(土) 14:12:31.00
814で速度低下しないということはリードポートの制約ではないような
824デフォルトの名無しさん:2013/07/27(土) 15:16:41.65
>>819
AVX2コードの
vpaddq ymm0, ymm8, ymmword ptr [mem1]
vpaddq ymm1, ymm9, ymmword ptr [mem2]
vpsrlq ymm2, ymm10, 1
add rsi, rax

mem1、mem2を32バイトでアライメントしたらIPC 4になりました。
御指摘感謝。

謎なのはAVX2のコードはこれでもIPC 4なのに、
vpaddq ymm0, ymm8, ymmword ptr [rbp]
vpaddq ymm1, ymm9, ymmword ptr [rbp+32]
vpsrlq ymm2, ymm10, 1
add rsi, rax

x64の場合は以下の両方ともIPC 3になってしまうこと。
add rax, r12
add rbx, [rbp]
add rdx, r13
add rdi, [rbp+32]

add rax, r12
add rbx, [mem1]
add rdx, r13
add rdi, [rbp]

最適化マニュアルではPort7がSimple_AGUになっているけど、
AVXでは整数ユニットが空いていてアドレス計算が同時にできるのだろうか。
x64ではIRP相対だけだとIPC4なのに片方が間接アドレスになると遅くなるのが不思議。
825デフォルトの名無しさん:2013/07/27(土) 15:44:07.55
load-opのaddじゃなくて普通にadd reg, regを4つ並べるとどうなるん?
826デフォルトの名無しさん:2013/07/28(日) 15:51:02.92
>>825
レジスタやIRP相対、レジスタ間接まではaddでもcmpでも差があるようには感じなかったけど、
インデックスレジスタを使用したらどちらも遅くなるものの、addの方が少し速い結果に。

これが3.1clock,2.6IPCで、
add rax, r12
add rbx, [rbp+r13+8]
add rdx, r14
add rdi, [rbp+r15+16]
add r8, r12
add r9, [rbp+r13+96]
add r10, r14
add r11, [rbp+r15+112]

cmpでは3.7clock,2.2IPCに。
cmp rax, r12
cmp rbx, [rbp+r13+8]
cmp rdx, r14
cmp rdi, [rbp+r15+16]
cmp r8, r12
cmp r9, [rbp+r13+96]
cmp r10, r14
cmp r11, [rbp+r15+112]

フォワーディングの効果でレジスタファイルのread負荷が軽減されたのかと
src側をr12とrbpのみに変更しても速度の違いはなさそうだった。
827デフォルトの名無しさん:2013/07/28(日) 15:52:08.08
SIMDだとインデックスレジスタ付きでも2.8clock, 2.86IPCと多少速かった。
vpaddq ymm0, ymm8, ymmword ptr [rbp+r8+32]
vpaddq ymm1, ymm9, ymmword ptr [rbp+r9+64]
vpsrlq ymm2, ymm10, 1
add rsi, rax
vpaddq ymm3, ymm11, ymmword ptr [rbp+r10+96]
vpaddq ymm4, ymm12, ymmword ptr [rbp+r11+128]
vpsrlq ymm5, ymm13, 1
add rsi, rdx
828デフォルトの名無しさん:2013/07/28(日) 16:19:25.03
Haswell面白そうだな

Sandy Bridgeセカンドマシンにして買ってみるか
829デフォルトの名無しさん:2013/07/29(月) 02:36:46.82
どうもSandyで測ってみると
port0,1,5に発行されるALU命令が必要とするクロック当たりのソース整数レジスタのポート数によって
port2,3に発行される(AGU行き)命令のスループットが制約を受けるような挙動をしている気がする

想像するに>>824の「x64の場合は以下の両方ともIPC 3になってしまうこと。」の例で
add rax, r12
add rdx, r13

add rax, 1
add rdx, 1
とかの即値加算にするとIPC=4になるのではなかろうか
830デフォルトの名無しさん:2013/07/29(月) 03:47:54.84
PRFのポート構成ってどうなってるんだっけ?
831デフォルトの名無しさん:2013/07/29(月) 12:08:54.59
MMXレジスタ間のmovdについて質問させてください。
Visual C++ 2010のインラインアセンブラを使用しています。

movd mm0, src1
psllq mm0, 32
movd mm1, src2
movd mm0, mm1

上のようなコードを書き、mm0の上位32bitにsrc1を、下位32bitにsrc2を格納したいのですが、
4行目
movd mm0, mm1
の部分で "error C2415: オペランドの型が無効です。"というエラーが出てしまいます。
どのようにすれば解決できるのか、どなたか教えてください。
832デフォルトの名無しさん:2013/07/29(月) 14:17:43.54
リファレンスくらい読めよ
833デフォルトの名無しさん:2013/07/29(月) 19:47:39.48
>>830
完璧に作られてるよ
834デフォルトの名無しさん:2013/07/29(月) 23:37:06.28
>>829
Haswellで>>824のaddの二つのレジスタオペランドを即値にしたら3・4番目ともIPC4になりました。
>>824のレジスタ同士の加算の片方だけを即値にすると2.2clk,3.6IPCになります。
インデックスレジスタを使うと遅くなり、>>814ではcmp、add共に問題がないので、
AGUでレジスタ参照があると影響が出やすいようですね。
SIMDでは影響が出にくいのはPRFが分離されていて参照数が被らないのも一因でありそう。
835デフォルトの名無しさん:2013/07/30(火) 02:58:40.52
確認乙

NehalemまでのRegister Read Stall的な何かがSandy以降にもあるのかね
この制約が言及されてる文献ってあるのかな
Agnerマニュアルにも載ってないし

ともかく当初の話題であるHaswellのALUについては
加減算比較論理はport0,1,5,6全てにあり、レジスタオペランドを使う限り
特にボトルネックはなく動くという認識でいいのかな
instlatx64の結果は測定方法がおかしい?、ということになるが
836デフォルトの名無しさん:2013/07/30(火) 03:34:45.22
>Agnerマニュアルにも載ってないし

特に制限が無かったって書いてあるけど

IntelがALUという場合、加算論理移動比較テストあたりまでだな。
AMDがALUという場合、シフトやLEAも入るけど。
837デフォルトの名無しさん:2013/07/30(火) 04:30:30.04
うん、だから今回話題になったような制約には言及してないと言いたかったんだけど
伝わらなかったかね
838デフォルトの名無しさん:2013/07/30(火) 08:14:25.20
addは4命令フルにリタイアしてるからレジスタファイルの書き込みは大丈夫そう。
計算結果が後続の命令のオペランドにならないcmpでも問題ないので
読み出しもレジスタ同士なら4IPC可能で、メモリ参照も直接アドレスを指定すれば
速度低下はしていません。
839デフォルトの名無しさん:2013/07/30(火) 12:03:32.22
>>838
4IPC可能な add reg1,reg2 だけど、
1ループ中の命令数を4000命令ぐらいにして
uOPキャッシュをミスさせた場合、IPCは3に落ちる?落ちない?

ところでこんな記述を見つけたんだけど、
http://www.inteler.uh-oh.jp/pdf/IFB004_Intel%27s%20Haswell%20CPU%20Microarchitecture_J_.pdf
Page 12
> AGU は、(base+offset)が2,000 未満のときは1 cycle で、
> (base+offset)が2,000以上、または(base+index+offsett) addressingを使用している場合に、
> 追加の1 cycle が付いた。

この「(base+offset)が2,000以上」ってどういう意味だろう??
840デフォルトの名無しさん:2013/07/30(火) 12:27:48.70
RWTの元記事 http://www.realworldtech.com/haswell-cpu/5/
普通にoffset(即値)が2K以上、という意味では?
レイテンシの話だから今回のケースには関係ないだろうけど
841デフォルトの名無しさん:2013/07/31(水) 02:08:45.70
>>839
814の8命令シーケンスを512回展開したら2.36clock,3.4IPCになりました。

レイテンシは、下のコードのoffsetを4096と8で比べても差がなくてよくわからないな…
align 64
table qword N dup (0h)

lea rsi,table
mov ebx,8
loop:
mov rax,[rsi+offset]
add rax,rbx
add rsi,rax
842デフォルトの名無しさん:2013/07/31(水) 09:23:28.02
>>841
814の8命令シーケンスをaddに替えてってこと?
というのも>>778の結果だとNOPやXORはuOPキャッシュミスしても4IPCをキープできるけど、
SUBやTESTやCMPは3IPCに落ちてしまうようなので、他の命令はどうなのかと思って。
ふと思ったんだけど、このSUB,TEST,CMPっていずれもマクロフュージョン対象命令であり、
NOP,XORはマクロフュージョンの対象じゃないなと。
マクロフュージョン対象命令は次の命令が条件分岐命令かどうか確かめる必要があるので
デコードになんらかの制限でもあるのかなぁ?と想像したもので。

offsetは2K未満と以上で差がなかったですか。
HaswellではSandyBridgeのAGU制限がなくなったということなのかな?
843デフォルトの名無しさん:2013/07/31(水) 21:45:09.52
>>842
addでもcmpでも変わらないですね。
レジスタ間xorはuOPミスヒットでも4IPC出てるみたいです。
844デフォルトの名無しさん:2013/08/01(木) 00:46:15.79
やはり通常、単純命令はデコード3基しか回らないんだろうな
コンプレックスデコーダーを使う命令が来れば4基動くかも、って感じなんだろう
845デフォルトの名無しさん:2013/08/01(木) 00:54:53.20
3基しか回らないなら3IPC以下になるはず
それにxorとかzeroing idiomsが効く命令で4IPC出る理由にもならない
846デフォルトの名無しさん:2013/08/01(木) 01:07:20.60
というか、Sandyでもadd reg,reg3つとmov reg,mem(RIP相対)で4IPC出るんだよね普通に
当然全部simple decoder行き命令だがuop cacheにヒットしないケースでもIPCは落ちない
847デフォルトの名無しさん:2013/08/01(木) 01:15:09.08
今のところすべての事象を合理的に説明できるのは
port0,1,5,6全てに命令が発行されると何クロックかに1回デコーダがサボる
という仮定だが
848デフォルトの名無しさん:2013/08/01(木) 01:18:06.53
>>846
その例だと、mov reg,regがコンプレックスデコーダー、add reg,regがシンプルデコーダで
デコードしていると言えてしまうのでは。
add reg,reg 6つとmov reg,mem 2つとか、
add reg,reg 9つとmov reg,mem 3つとかの場合で、
uop cacheをミスさせたらどうなる?それでも4IPC出るなら
add reg,regがコンプレックスデコーダーでデコード出来ている証拠になるけど。
849デフォルトの名無しさん:2013/08/01(木) 01:23:07.44
>>847
843で
> レジスタ間xorはuOPミスヒットでも4IPC出てるみたいです。
という事なんだから、
port0,1,5,6全てに命令が発行されもデコーダはサボっていないようだが。
850デフォルトの名無しさん:2013/08/01(木) 01:29:13.79
>>845
100%uOPキャッシュミスしてる訳ではないので、3IPCを超えるのは別におかしくない。
あとzero idiomsは関係ないかと。xor eax,eaxとsub eax,eaxは共にzero idioms
だけど、xor eax,eaxは4IPCキープ、sub eax,eaxは3IPCに低下。(>>778)
851デフォルトの名無しさん:2013/08/01(木) 02:17:30.23
>>846
ああなるほど、simple decoderでしか処理できない命令と、complex decoderでしか処理できない命令と
その両方で処理できる命令の3種ある、ということね

>>850
>>755の結果ではsubがzeroing idiomsが効く場合のみ4IPCになってたからその話をしてたのだが
まあこれはどんな条件で測ったか分からんから何とも言えんか
852デフォルトの名無しさん:2013/08/01(木) 04:54:22.45
でもって、Sandyで代表的な1uop命令を測ってみたところ
and, add, sub, cmp, test, inc, dec
はsimple decoderのみで処理可能な命令で
or, xor, not, mov, movsx, lea, shl, shr, sar, neg, SSE/AVX命令群
はsimple/complex両方で処理可能な命令、ぽい

で、よく考えてみると、前者は全てmacro fusionが可能な命令で
後者にはmacro fusionが可能な命令は含まれていない
ということで>>842の推測は正しそう
cmpとtestしかfusionできないCore2,Nehalemではどうなのかも調べないといかんね

Ivyまでならバックエンドと同じ帯域なので大した影響はないとは言え
一応これも4-1-1-1ルールに引っかかるようなので命令の並びによっては若干IPCに悪影響があるね
853デフォルトの名無しさん:2013/08/01(木) 05:38:20.78
どうやって測ったんだ?
854デフォルトの名無しさん:2013/08/01(木) 08:30:14.04
>>852
やはりそうでしたか。
手持ちのマシンのCore2ではcmpとtestは4命令同時デコードできているようです。
確かめた方法は
test eax,eax×24連続,mov ecx,[edx]×8連続,test eax,eax×24連続,mov ecx,[edx]×8連続,...
のコードで4IPC出る事を確認。cmpも同様。

Sandy以降、コンプレックスデコーダでマクロフュージョン対象命令がデコードできなくなった
という事なら、最適化マニュアルの「4uopsまでのすべてのIA-32,Intel64命令をデコード可能」
という記述 >>791 は誤りになるね。
855デフォルトの名無しさん:2013/08/01(木) 15:05:22.43
Nehalemでも同様。ということでSandy以降の制限のようだ。
こういうIntel流の細かいサボりがトランジスタコストを下げて電力効率を上げてるんだろうなあ...
856デフォルトの名無しさん:2013/08/01(木) 19:46:16.59
3命令しか実行できなかったんだから、3命令デコードで問題なかったんだろ
実際Haswellが出るまで誰も問題にしなかった
そのHaswellの4命令実行はμOpsキャッシュからの供給を当てしたものだった
実際μOpsキャッシュは80%のヒット率があるなら大半これで間に合うという判断だろうな

skylake以降は残り20%の対策をしてくるだろうけどな
857デフォルトの名無しさん:2013/08/01(木) 21:38:35.64
>>844,845
xorを1ループ4096命令並べたバージョンでも4IPC出てるのは下のようにオペコードの短い
32bitレジスタを指定したレジスタ間xorの場合で、>>814の命令をxorにして4096並べたバージョンでは
2.2clock,3.6IPCでした。
テストに使っているプログラムはいずれも64bitモードで、32bitモードは試していません。

xor eax, ebx
xor edx, ecx
xor esi, ebp
xor edi, ebx
xor eax, ebx
xor edx, ecx
xor esi, ebp
xor edi, ebx

>>778ではuOPキャッシュの繰り返しのサポートを推測しているけど、
uOPキャッシュって再度実行するためにデコード結果を格納しておくものだから
ループでなければキャッシュしても仕方ないよね。
ということは、単なる擬似LRUだけではなく、ループ内と判定された部分はキャッシュから
消去されにくくなってる可能性はない?
858デフォルトの名無しさん:2013/08/01(木) 22:03:25.70
>>857
じゃあ32bitレジスタを指定したレジスタ間addを1ループ4096命令並べたら場合はどうなるの?
859デフォルトの名無しさん:2013/08/01(木) 22:11:07.89
>>858
add,cmp,subは64bitレジスタと32bitレジスタはどれもほぼ同じ速度で、
64bitレジスタ間だとほんの僅か速い傾向です。
860デフォルトの名無しさん:2013/08/01(木) 22:33:47.60
r8d-r15dを使った場合はどうでしょう
861デフォルトの名無しさん:2013/08/01(木) 23:23:35.17
>>860
REX.Dは64bitレジスタと同じ結果になりました。
862デフォルトの名無しさん:2013/08/01(木) 23:29:19.34
xorでも2バイト命令は4IPCで、3バイト命令だとIPC落ちるということかな。
なんかいろいろと制限ありそうだね。
863デフォルトの名無しさん:2013/08/02(金) 01:15:42.25
Sandyだとプリデコーダの制約が見えてる気がする
16バイトあたり4命令に近いほどスループットが高い感じ
(4命令で16Bを超えない限りREXが付いたりと命令長が長いほうが速い)

Core2だとマニュアルにも載ってる16Bあたり6命令/clkのプリデコーダ制約があったけど
Sandyでも2B*3+4B*1の繰り返し(7命令/16B)だと3.2IPCぐらいしか出ないから
似たような制約があるっぽい (Ivyも同様)

Haswellで2B*4の繰り返しで4IPC出るなら改善されたことになるが
864デフォルトの名無しさん:2013/08/02(金) 01:43:26.34
もしプリデコーダの並列度が6->4になってるとしたら
最も影響が出るのは3B命令の連続じゃないのか
2Bと4B以上は変わらんし、1Bは仮に変わってもわからんだろう
865デフォルトの名無しさん:2013/08/02(金) 01:58:18.75
ああ、確かに2B連続なら結局2サイクルで8命令プリデコードできるから影響ないな
失礼
866デフォルトの名無しさん:2013/08/02(金) 19:56:57.86
>>778のprefixed cmp(8)の場合、7バイト超えているからコンプレックスデコーダでしかデコード
できないはずなのにかなりのパフォーマンスが落ちにくくなってるよね。
例えば、グラフ14の8*1.5kuOPになる12KB以上の部分はuOPキャッシュが機能しているのを示していて、
これは分岐予測やループ検出の応用でuOPキャッシュのヒット率が上がっているの示しているんじゃないか?
867名無し募集中。。。:2013/08/02(金) 20:28:05.08
>>863
7命令だと6命令と1命令でプリデコードに2サイクル掛かるからそのくらいで妥当じゃないの?
868デフォルトの名無しさん:2013/08/02(金) 20:35:26.52
7バイト超の命令はコンプレックスデコーダでしかデコードできないなんて制限あったっけ?
Core2でRMMA実行してみたけど、Prefixed CMP #1〜4 どれも16bytes/cycle出るので、
シンプルデコーダでもデコード出来ているようだが。
869名無し募集中。。。:2013/08/02(金) 20:46:45.90
>>7バイト超の命令はコンプレックスデコーダでしかデコードできないなんて制限あったっけ?

そんなのPenproの頃の制限
870デフォルトの名無しさん:2013/08/02(金) 20:55:01.58
PenProの頃はあったのか。
871デフォルトの名無しさん:2013/08/02(金) 21:03:57.44
>>868,869
グラフ14のIvyの100KB付近は1IPCになってるけど。
872デフォルトの名無しさん:2013/08/02(金) 21:25:41.48
100KBという事はL1命令キャッシュもミスするから、
それくらい遅くなるのは不思議じゃないと思うが。
873デフォルトの名無しさん:2013/08/02(金) 23:08:53.53
>>867
なので似たような制約があるっぽいと書いたつもりだが
874名無し募集中。。。:2013/08/02(金) 23:45:42.64
875デフォルトの名無しさん:2013/08/02(金) 23:53:23.93
しかし、クロック計測スレが落ちてしまったのが悔やまれるな
876デフォルトの名無しさん:2013/08/03(土) 00:08:37.63
まぁHaswellはL1命令キャッシュミスしても16bytes/cycle出るようになったのはすごいやね。
これの効果が出てるということだろうね。

> Haswell の命令cache は、miss をより高速に扱えるように最適化された。投機的なITLB
> とcache access がprefetch の恩恵を向上すべくより優れたtiming でsupport されるに加
> え、cache controller が命令cache のmiss を並列に扱うこと関して、ずっとより効率的に
> なっている。
877デフォルトの名無しさん:2013/08/03(土) 01:41:24.89
>>778だとL1Iミス以前から速度が落ちてるからデコーダの制限じゃなかったですね。
>>876
HaswellだとL1IからL2の間のサイズでの改善が素晴らしいなぁ。
878デフォルトの名無しさん:2013/08/05(月) 23:38:22.94
Intel Intrinsics GuideとSDEがAVX512に対応してたのね。
ttp://software.intel.com/en-us/intel-isa-extensions
879デフォルトの名無しさん:2013/08/06(火) 00:21:46.91
>>840
実は公式の最適化リファレンスマニュアルにも書いてある。
base+offset < 2048ってbaseも含まれるかのような微妙な記述なんだよな。
base+offset < 2048のときがたまたま速くなってしまうだけで、通常のケースは5 cycleってニュアンスの可能性もありえなくもないw
詳しくは、Table 2-12.とその周辺の文を参照。
880デフォルトの名無しさん:2013/08/06(火) 20:44:56.94
>>870
PenProどころかPenMもそうだよ
最適化マニュアルに書いてある。
881デフォルトの名無しさん:2013/08/14(水) 20:44:41.33
HaswellのWindows8マシンにCodeAnalystをインストールしたらOSが起動しなくなった。
セーフモードではアンインストールができずに詰んだかとも思ったけど、
セーフモードでレジストリエディタを起動して、
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CA_なんたら
のサービスの2つのキーのStartエントリを4に変更することで起動に成功した。

CodeAnalystは開発が終了しているので、HaswellマシンにはCodeXLを使いましょう。
882デフォルトの名無しさん:2013/08/28(水) 18:49:28.51
VC2012 x64コンパイラの_mm256_extracti128_si256バグにハマってしまった。
当面は_mm256_extractf128_si256使って回避した方がいいよ。
883デフォルトの名無しさん:2013/08/28(水) 21:19:21.32
情報サンクス!!
884デフォルトの名無しさん:2013/08/29(木) 12:10:52.81
そう言えばCode Analystを入れている時にパイプラインが途切れている場所を
発見する度に(´・ω・`)となっていた記憶があるな

もう入れてないや
885デフォルトの名無しさん:2013/08/30(金) 00:03:34.84
俺も試しにCodeAnalystをインスコ・・・う、動かん orz
XPはもうサポート外なんすね。少し旧い3.4落として入れたら動いた。
886デフォルトの名無しさん:2013/08/30(金) 19:59:00.00
HaswellのSIMD命令組み合わせの影響を調べてみた。
www1.axfc.net/uploader/so/3012766
887デフォルトの名無しさん:2013/08/30(金) 20:48:32.43
866はTBが効いた状態になってるから少し数値がずれちゃってる。
さっき電源オプションでプロセッサの最大状態を99%にしたら切りのいい値になったから
これだとTB無効にしたのと同じ結果になるのかな?
888デフォルトの名無しさん:2013/09/01(日) 13:14:58.61
gather遅い…
マイクロコード実行で他の命令が阻害されてるのか、maskmov的な機能がオーバーヘッドになってるのか、
レイテンシが長くなりがちな上位レーンを先に処理しないからなのか…

SIMD掛け算やymmのレーン間をアクセスする命令のレイテンシも前の世代より長くなってるみたいだから
そこがクリティカルパスにならないように工夫しなくては…

gatherに似たアプローチでデータをかき集めるより、部分的なSoA形式で並列化と局所化のバランスを
取るのがいいのかな。
889デフォルトの名無しさん:2013/09/01(日) 13:30:50.27
gatherって明らかにレイテンシかかりそうな処理だよね。
やっぱ隠蔽するにも限界があるのかな。
890デフォルトの名無しさん:2013/09/01(日) 14:06:20.05
複合命令でも必要なレジスタが少なくて済むのは便利だっだったりするんだけどね。

要素が順番に並んでないとデータ並列化のオーバーヘッドが無視できなくて、
完全にSoAにして要素が多数のページに分散するとメモリアクセスがボトルネックになる可能性があるから
スプリットマイニングの要領でSoA形式に変換した方がいいのかなって思ったり。

ポインタ計算をAVX2でやると32bitと64bitのコードを変更しなきゃならないのは面倒か…
891デフォルトの名無しさん:2013/09/09(月) 21:50:56.04
gatherとかはお試し実装みたいな感じで
SkyLakeでかなり改善されるらしい
892デフォルトの名無しさん:2013/09/13(金) 19:27:14.31
Agnerの最適化マニュアルが更新されてIvyやHaswellへの言及が追加されたね

実はこのスレでHaswellの4ALUに関する議論があった後に
Agnerのblogでmacro fusion可能な命令のデコード制約について議論したのだけれど
その制約について新たに言及されるようになった (microarchitecture.pdf、124ページ) ようで
議論に参加した皆さんありがとうございます
893デフォルトの名無しさん:2013/09/14(土) 00:50:12.30
末尾デコーダにfusion可能な命令がくると保留されて次のクロックに第1デコーダで処理されるって?
そんなアホな実装あるかなあ
後ろにjccがあってトントン、なかったら丸損なんだから
単純に一命令として処理した方が得じゃん
894片山博文MZコスモ ◆T6xkBnTXz7B0 :2013/09/15(日) 13:25:16.36
「VEX.NDS.128.66.0F.WIG」
この意味を教えて下さい。
895デフォルトの名無しさん:2013/09/15(日) 15:51:41.83
>>894
「AVX VEX」でぐぐれ
896片山博文MZコスモ ◆T6xkBnTXz7B0 :2013/09/16(月) 17:27:55.98
AVXって32ビットCPUでも使えるの?
897デフォルトの名無しさん:2013/09/16(月) 17:37:54.01
Intelのマニュアル読めよ
898デフォルトの名無しさん:2013/09/16(月) 17:41:42.50
Piledriverちゃんのネタ感が

The Piledriver is particularly bad on 256-bit stores with a throughput of
one 256-bit store per 17 clock cycles in my measurements (aligned).
17サイクルに1回って…

The throughput for 128-bit FMA3 instructions on Piledriver is one instruction
per clock, while the throughput for 128-bit FMA4 is two instructions per clock.
何が起こってるの…w
899,,・´∀`・,,)っ-○○○:2013/09/16(月) 21:16:44.01
まあ、SSEのときからStoreは極端に弱かったからね。

> The throughput for 128-bit FMA3 instructions on Piledriver is one instruction
> per clock, while the throughput for 128-bit FMA4 is two instructions per clock.

これはひょっとしたら故意に性能を落としてるかもしれない(FMA4を使って欲しいがため)
900,,・´∀`・,,)っ-○○○:2013/09/16(月) 21:28:11.89
ユーザーがAMDのCPUを使うこと自体に興味を失ってしまっては元も子もないけど。
Haswell-EXが出るまでに256bit化しないとHPC界隈からも見捨てられる気がする。

AVX-512って実質的なYMM32レジスタ化だよな
901デフォルトの名無しさん:2013/09/16(月) 22:01:45.19
andoさんとこで取り上げられてたけど、AMDは既にHPC界隈では相手にされてない感が...
http://www.hpcwire.com/hpcwire/2013-08-20/hpc500_q2_call_recap.html
902Socket774:2013/09/16(月) 22:56:39.55
steamrollerで256bit化するっぽいけど、今でさえ高い消費電力が、
256bitFPUでフル稼働したらとんでもないことになりそうだ。
しかもスチームってフロントエンドも二重化するらしいし。
903デフォルトの名無しさん:2013/09/16(月) 23:10:54.98
メモリオペランドが複数の命令に分解されるのと一緒じゃないのかな。
Intelはmove eliminationでFMA3でも大丈夫だと判断したんだろうとあったから、
FMA4の実装してたら同じことになってたのかもね。

Intel CPUにはFPユニットのWarm upペナルティというのがあったから
AMDでも単純に消費電力が増えるわけでもないだろうし、
HaswellもOCCTではかなりの爆熱状態になるよ。
904,,・´∀`・,,)っ-○○○:2013/09/16(月) 23:21:56.17
> FMA4の実装してたら同じことになってたのかもね。

元々FMA4自体はIntelが最初に計画したものでFMA3のほうが後から
変えたものだ。

しかしimm8をレジスタオペランドとしてとる命令は複合デコーダパスだから
μOPs cacheを外すと極端にスループットが落ちることは現実問題として
あり得たと思う。

FMA3の最大のメリットは、3レジスタオペランドならシンプルデコーダでも
それほど手を入れなくてもデコードできることだろう。
905Socket774:2013/09/16(月) 23:22:58.08
だからだよ。
Haswellでさえそうなんだから、steamrollerじゃ悲惨だろ
906デフォルトの名無しさん:2013/09/16(月) 23:30:22.86
steamrollerはHotChipsの128-bit FMACと書いてあるスライドしか見たこと無いな
あれからデータパスを1から作り直してるのか?
907,,・´∀`・,,)っ-○○○:2013/09/17(火) 13:14:27.09
>>890 亀だけど
> ポインタ計算をAVX2でやると32bitと64bitのコードを変更しなきゃならないのは面倒か…

へ?
ベースアドレスは汎用レジスタで持てばいいからYMMレジスタにはそのオフセット(添字)の
配列を格納するだけでいいはずだけど?(32ビットでたいていは足りるよね)
vgatherを使ったコードでも32ビットと64ビットでそれほど書き分けは必要ないはず。
908,,・´∀`・,,)っ-○○○:2013/09/17(火) 13:18:13.13
↑Intrinsics使う前提ね
909デフォルトの名無しさん:2013/09/22(日) 13:16:50.45
__m128の配列を宣言する場合、__m128といえど
16バイト境界に置かれないので__declspec(align(16))で修飾しなければならない。
void func(){
__declspec(align(16)) const __m128 v[10];}

これはstatic配列でも同じですか?
void func(){
static const __m128 v[10]; // __declspec(align(16))は必要?
}
910デフォルトの名無しさん:2013/09/23(月) 08:54:20.05
>>909
そもそも_m128にalign(16)の宣言がついてるからいらないのでは
911デフォルトの名無しさん:2013/11/04(月) 22:40:13.68
初心者質問おk?
VS2010のコンパイラ組み込み関数で
128 bit整数 0x11111111 22222222 33333333 44444444 uLLLを
__m128iにセットするにあたり
_mm_set_epi32(0x11111111, 0x22222222, 0x33333333, 0x44444444)
とやれば事足りると思うんですが、

これとは別に
_mm_setr_epi32(0x44444444, 0x33333333, 0x22222222, 0x11111111)
とやっても結果・吐かれるアセンブリコードともに違いが無いみたいなんですが

なんでset系はr無しとr有りの二種類あるのですか
(特にr系の存在意義とか知りたい。)
912,,・´∀`・,,)っ-○○○:2013/11/04(月) 23:16:20.11
書き方の好みの問題。
いわゆるシンタックスシュガー
913デフォルトの名無しさん:2013/11/04(月) 23:19:37.38
>>911
int i[4] = {0x44444444, 0x33333333, 0x22222222, 0x11111111};
それを32bit整数の配列で表すと、こうなる。
これと同じように、アドレスの小さい順に書きたいことも多い。
914911:2013/11/05(火) 07:04:52.90
>>912,913
回答ありがとうございます。納得いたしました。
シンタックスシュガーかなーとは思いましたが、ここ↓のサンプルで
ttp://stackoverflow.com/questions/9348964/128-bit-sse-counter
不自然にr付きを使ってたので気になってしまいましたもので質問させていただきました
915デフォルトの名無しさん:2013/11/05(火) 19:34:34.49
シンタックスシュガーっぽいのはコンパイル時に値が確定してるからじゃないのかな
さすがに関数を指定したら生成コード変わるでしょ。
916デフォルトの名無しさん:2013/11/06(水) 01:25:34.20
ふとオモタが、__stdcallな呼び出し規約が標準であるPascal系等の言語から
直に_mm_setr_XXXX()を呼ぶと_mm_set_XXXX()と同じような感じになるのではないだろうか…
糖衣構文も、それなりに理由があるからこそ設けられるのだと思うし…

ていうか、ぶっちゃけ次の質問なのですが、現実問題として_mm_empty()っていつ書けば良いのですか?
MMX命令を使い終わってからFPレジスタを使い出すまでの間っぽいことが書いてあるのですが、
そのポリシーを、中でFPレジスタを使っているのか否か定かでない他人様のコードとの
混在状況においてまともに順守するとなると、他人様のコードを呼ぶ前に必ず書かねばならないという
こと?
917デフォルトの名無しさん:2013/11/06(水) 08:03:57.81
基本はできるだけFPU命令はFPU命令でまとめる、MMX命令はMMX命令でまとめる。その上で、
・MMX命令(群)を実行するまえにFPUレジスタスタックを空にしておく。
・FPU命令(群)を実行するまえにEMMS命令(=mm_empty())を発行しておく。

質問については、いろいろやり方はあると思いますけど、、、他人様のコードの動きがわからなくてそもそもうまくいくのかな?

参考)
・x86アセンブラ入門(CQ出版..pp222)
・Intel Software developper:s manualのEMS命令の項
918,,・´∀`・,,)っ-○○○:2013/11/06(水) 21:29:16.36
MMX使わないなら書く必要は微塵も無い。
てか今更書く必要あるの?64ビットだとMMX関連はコンパイルエラーになるんだが。
919デフォルトの名無しさん:2013/11/06(水) 21:40:18.53
団子さん、今でもアセンブラやイントリでガリガリ書くことある?
もうSIMD以外使う意義なくね?
920,,・´∀`・,,)っ-○○○:2013/11/06(水) 22:22:08.79
bsr/bsfとかpopcntみたいな特殊なビット操作を組み込み関数なしでできるなら
できればそうしたいな。
まあ、使うケースとしてSIMDと併用することが多いんだが。
921919:2013/11/07(木) 00:20:57.96
やっぱSIMDだよなぁ。
512bitSIMD楽しみだ。
922デフォルトの名無しさん:2013/11/07(木) 02:09:45.32
MMXはSSE2整数系の命令に代替できるんだっけ?
923デフォルトの名無しさん:2013/11/07(木) 11:18:32.78
なんか足りないのある?
924,,・´∀`・,,)っ-○○○:2013/11/07(木) 17:03:41.08
足りてる
925デフォルトの名無しさん:2013/11/07(木) 19:28:08.88
_mm_packhiとか_mm_unpackhiはレジスタの長さが変わると影響を受けるよ
あとSSEはメモリオペランドのアライメントが合ってないと例外になるとか
926,,・´∀`・,,)っ-○○○:2013/11/07(木) 21:54:53.67
そーいやXeon Phiのミスアラインロードが妙に使いにくいようだが・・・
アラインメント境界とキャッシュライン境界が一致するからあんな感じなのかな
927916:2013/11/10(日) 03:45:14.56
レスdクス、

いまいちMMXとSSEとSSE2とその他とAVXの区別がついていなかったのですが、
Intel様がタダで配っている次のイントリンシック命令分類アプリで見たら色分けされてて大変良くわかったにょろ↓
ttp://software.intel.com/en-us/articles/intel-intrinsics-guide

128 bitリニアのビットシフトとか、128 bitリニアの加減算がやりたかっただけなのだけど、上の一覧表のおかげで作業がはかどり完成すた、
汎用レジスタとのやりとりは、setよりもinsertで(ただし32 bit値を)ぶちこむ方法で、メモリを経由せずに直に高速に値をレジスタ渡しできる
あとはshuffleかunpackで増やしたり移動させたりでくる、
928,,・´∀`・,,)っ-○○○:2013/11/10(日) 12:55:36.88
insert/extract命令は発行ポートが1個しかないしレイテンシも大きいので、
場合によってはメモリストアしてロードしたほうがかえって性能出る場合も
あるよ。

たとえばの話、レイテンシ3だから同じXMMレジスタに4回insertしたら
合計で12クロックのレイテンシチェインが生じる。
ユニットの空きにもよるけど、
mov(store) 4回+movdqa 1回のほうが短いサイクルですむこともありうる。

ストアデータはバッファリングされるのですぐに呼び出す場合は
比較的短いサイクルですむ。
929デフォルトの名無しさん:2013/11/10(日) 14:26:58.95
>>928
説明が端折りましたが現状、だいたい32 bitを1回書くだけで事足りるような使い方ばっかりです…

下位64ビットのMSBの1/0値を上位64ビットに足す例(キャリーの伝搬)↓
z = _mm_setzero_si128(); // これはそのうち不要になる予定
// ...
c = _mm_insert_epi32(c, 0, 0); // R0を0にする。R1のMSBがキャリー
c = _mm_cmplt_ep(c, z); // R1のMSBが1ならR1=0xffffffff, 0なら0x00000000になる。
c = _mm_shuffle_epi32(c, 0x50); // 元R1をR3、R2にコピー、元R0をR1、R0にコピー(下位64 bitは0)
y = _mm_sub_epi(y, c); // 元のcのR1のMSBが1なら-1が引かれる=1加算。

それはそうとして、ようわからんのですが、レイテンシが3だとして、レイテンシ3が連続する限りは
パイプラインのステージの競合が起きず、スループット×命令数、で消費クロックサイクルが済むのでは…(つまり3×4よりは少ない
レイテンシが2から3に変わるとか、不連続部分でライトバックステージの競合が生じたときレイテンシがそのまんま遅延分になる、
というだけなのでは…
930デフォルトの名無しさん:2013/11/10(日) 14:51:07.84
なんかこう、うん、まあ、頑張れ
道は長いぞ
931,,・´∀`・,,)っ-○○○:2013/11/10(日) 15:11:35.04
原則的には書き込んだ結果を後続の命令で参照するときに依存関係が生じる。
書き込み先が別々のレジスタ、あるいは全書き換えなら依存は発生しない。

部分書き換えだと前の演算結果が確定するまでストールする。
932デフォルトの名無しさん:2013/11/10(日) 18:32:42.21
いやそれが>929のcへの繰り返し代入部分を別の中間変数(s、t、rを経由とか)に変えても
VC2010において、吐かれるアセンブリコードが全く変わらないっていうか、(xmm0とxmm2しか使われない)
もはやインラインアセンブラで手動でレジスタの分散が必須?

ていうか、次のコードになるのです…
xor eax,eax
pxor xmm1,xmm1 // (A)
pinsrd xmm2,eax,0 // (B)
pcmpgtd xmm1,xmm2 // (C)
pshufd xmm1,xmm1,50h // (D)
paddq xmm0,xmm1 // (E)

部分書き換えにあたるのは(B)ですが、xmm2が依存する演算は直前2命令より前に開始されているはずなので、
そいつらのレイテンシが3以下なら(B)実行時点で解消済(よって(A)→(B)→(C)でパイプラインストールは生じない)と観て良く無くないです?
同一ステージの衝突を避けるために、1サイクル単位のストールは引き起こされるかもしれないが、
パイプライン全クリアみたいな極端なストールは起きないのでは…
933デフォルトの名無しさん:2013/11/10(日) 22:31:08.45
日記帳モードサーセン;

Q1:
レイテンシの意味がようわからんのですが、パイプラインの段数が20段ぐらいあるとして、
データ入力ステージから(実行ステージを経て)データ出力ステージに至るまでのサイクル数、と見て良いのでしょうか

Q2:
とすれば、漏れのCPUは06_1Eので、
(A)-(B)間 スループット1 (∵依存関係無し、pxor xmm, xmm スループット0.33)
(B)-(C)間 スループット2 (∵依存関係有り、pinsrd xmm, reg, imm レイテンシ2)
(C)-(D)間 スループット1 (∵依存関係有り、pcmpgtd xmm, xmm レイテンシ1)
(D)-(E)間 スループット1 (∵依存関係有り、pshufd xmm, xmm, imm8 レイテンシ1)

ということで、(B)-(C)間以外ではあんまりストールしない、で合ってます?
(B)-(C)間で>928の通りになることは理解いたしますた、

Q3:
先行する演算の結果に依存する演算において、ストールはxmmレジスタの全ビットの確定まで続くのでしょうか。
それとも、値が確定したパックからどんどん先行するんでしょうか(shuffleとか)。
普通のアーキテクチャならパイプラインの入り口で命令フェッチ→デコード、という手順を踏むので前者以外あり得ないが、
インテルのやつは命令キャッシュに水平マイクロコードを格納するとか聞いたので、もしかしたら…
934,,・´∀`・,,)っ-○○○:2013/11/10(日) 22:51:09.96
Q1.
正解

Q2.
> (A)-(B)間 スループット1 (∵依存関係無し、pxor xmm, xmm スループット0.33)
1Eってどれだったっけ?

pxorによるゼロクリアで依存関係解消のヒントとして使えるのは
Sandy Bridge世代からなので、
それより前に同じレジスタをレイテンシチェインの長い命令で使ってたとしたら
それ以前のCPUでは別のレジスタに割り当てたほうが性能が出る可能性はある。

とりあえずそんなに悪いコードには見えないけど、VC++のSSE/AVX関連の最適化
って結構タコだからあてにはしないほうがいいことは間違いない。

Q3.
> 先行する演算の結果に依存する演算において、ストールはxmmレジスタの
> 全ビットの確定まで続くのでしょうか。
これが正解。
一部だろうが全部だろうが値が確定するまで後続命令は発行できない。
935デフォルトの名無しさん:2013/11/11(月) 01:42:55.73
>>934
>pxorによるゼロクリアで依存関係解消のヒントとして使えるのは
>Sandy Bridge世代からなので、
pxorで依存関係解消ができないのはMMX Pentium Proだけ?だと思ってたけど。
Zero Idioms化されたのがSandyじゃなかったっけ?

>>933
Q1について
最適化マニュアルに書いてあるレイテンシとかスループットは基本的に実行ユニットのものだよ。

Q2について
pinsrdはパーシャルアクセスになる命令ではないはず。
レジスタのパーシャルアクセスでもPentium3以前だとレジスタのライトバックまでストールしてたと思うけど
今使われているものは値の確定後に1レイテンシ分のマイクロ命令追加で済んでるはずだと思った。

細かいストールを気にするより、>>932がループだとして、C、Eの後に依存性を切るチャンスがあるから
そこで次のサイクル以降の処理が効率よく実行できるようなコードにするのがパフォーマンスを引き出すコツだよ。
数クロック単位の遅れが直接問題になることなんてまずないし。

pinsrdだとシャッフルユニットがボトルネックになりそうだから、AVX2が使えるなら_mm_cvtsi32_si128と_mm_blend_epi32や
AVX2無しならblendの代わりにpandとpor使ってもいいかもね。
936デフォルトの名無しさん:2014/01/13(月) 15:00:28.68
質問です。
GCCだと _mm_mul_ps を __builtin_ia32_mulps に出来て、更に
直接 *(かけ算) でも同じアセンブラに展開されるけど、他にどんな
演算子が実装されているかのドキュメントってどこかにあるもんでしょうか?

演算子を使った方が移植性が高くなるんで、極力使いたいもので。
(他にビット演算が出来そうなのは確認済み)
937デフォルトの名無しさん:2014/01/13(月) 18:56:04.00
ここにあるけど
http://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html

移植性は**intrin.hをインクルードして_mm_mul_psのような正規の組み込み関数を使うのが一番高いのでは?
gccだろうが、clangだろうが、MSVCだろうが、iccだろうが受け付けるし。
938デフォルトの名無しさん:2014/01/13(月) 19:25:24.68
>演算子を使った方が移植性が高くなるんで、極力使いたいもので。
gccの組み込み関数を使うと移植性が低くなるわけだが
ドキュメントはgcc builtin functionsでググれ
939デフォルトの名無しさん:2014/01/14(火) 01:21:30.62
>>937,938
どうもです。見てみます。
_mm_mul_psの記法はARMのNEONとかには使えないから、出来るだけ四則演算とか
使った方が移植性が高いと思った次第です。
NEONで動かした事がないんで全くの推測ですが…
940デフォルトの名無しさん:2014/01/14(火) 03:33:23.32
ああ移植性って異なるISA間での移植性か...
SIMD使うなら速度を気にしてるんだろうし、コードパス自体を分けたほうがいいと思うなあ
941デフォルトの名無しさん:2014/01/14(火) 10:27:44.60
>>937のドキュメントを見るとISAに依存してなさそうなshuffleとかもあるし、
比較演算使うとレジスタが-1になるんで、これでselectとかも実装できそう。

完全には無理そうだけどほとんどはISAに依存しない書き方ができそうなんで、
もう少し調べてみます。
942デフォルトの名無しさん:2014/01/14(火) 15:32:49.93
環境依存するコードは素直にそれぞれ書くしかない
943デフォルトの名無しさん:2014/01/14(火) 17:19:30.58
SIMDをISA間で共通化させるっていうのは無理だし、
現状ですらSSEとAVXも分けて書かないといけないから、
普通にハードウェアチェックをしたあとストラテジー
パターンで切り分けるのがいいんじゃないか?
そのほうがコードのメンテも楽だし。
944デフォルトの名無しさん:2014/01/14(火) 17:59:52.00
調べると言ったんで一応書いておく
外積は以下のように書けた (GCC 4.8.1)
// (A1, A2, A0, A3)
// *
// (B2, B0, B1, B3)
// -
// (A2, A0, A1, A3)
// *
// (B1, B2, B0, B3) ← 外積の定義 (A3,B3は0決め打ち)

__m128i mask1 = { 1, 2, 0, 3 };
__m128i mask2 = { 2, 0, 1, 3 };
__m128 result = __builtin_shuffle(A, mask1)
* __builtin_shuffle(B, mask2)
- __builtin_shuffle(A, mask2)
* __builtin_shuffle(B, mask1));

これでintrinsicで書いた時と全く同一のアセンブラコードが出るのを確認した
>>943
それは、
http://gcc.gnu.org/wiki/FunctionMultiVersioning
っていう便利な機能が4.8から入ったよ (まだx86だけっぽいけど)
945デフォルトの名無しさん:2014/01/14(火) 18:05:04.05
>>944はISAに依存した命令は書いてないからNEONでも動きそうな気配はある
ただ全くの未検証
946デフォルトの名無しさん:2014/01/15(水) 01:40:45.24
FunctionMultiVersiong便利そうだけど
これコンパイル時のフラグはどうしたらいいんだ?
SSE4.2有効にしたらversiong指定していない関数もSSE4.2使って最適化コンパイルされてしまうんじゃね
947デフォルトの名無しさん:2014/01/15(水) 10:27:44.01
>>946
まだ試してないから何とも言えないけど、1ファイル1関数にすればいいはず。
で、個別に最適化オプションを付けるしかないね。
948デフォルトの名無しさん:2014/01/15(水) 10:30:07.57
1ファイル1関数って言い方は変だった。
SSE3とかSSE4とかの各バージョン毎に1ファイルにすればいいかな。
949デフォルトの名無しさん:2014/01/15(水) 11:12:59.14
gccに-march=sse2とか渡しても当該の関数だけ-march=sse4.2扱いしてくれるんじゃねえの?
別ファイルに分けるんならこんな機能要らねえじゃん
950デフォルトの名無しさん:2014/01/15(水) 11:24:02.14
> 別ファイルに分けるんならこんな機能要らねえじゃん
え?何か誤解してないか?
実行時に拡張機能を自動判別して関数をディスパッチしてくれる機能だぞ。
単純に手間を削減してくれる便利機能だと思うけど。
どっちにしろ、実際に試してみないと何とも言えない。
951デフォルトの名無しさん:2014/01/15(水) 14:08:20.13
たぶんFunctionSpecificOptと組み合わせろってことだろうけど
intrinとかのヘッダーファイル読むときにmsse*ついてないと読めない気がしたんだよな
952デフォルトの名無しさん:2014/01/16(木) 01:48:50.77
結局関数ポインタで切り替えるわけだから、gccのリンカじゃインライン展開してくれないだろうな。
953デフォルトの名無しさん:2014/01/17(金) 15:12:58.25
AVX2命令使うとi7がチンチンに熱くなるんだけど
消費電力大きいのか?
954デフォルトの名無しさん:2014/01/17(金) 19:45:19.94
SSE利用時と比べて電圧が上がるんじゃなかったっけ
955デフォルトの名無しさん:2014/01/18(土) 01:18:34.85
AVX2命令使うとチンチンが熱くなるんですが
どうしたらいいですか?
956デフォルトの名無しさん:2014/01/18(土) 01:21:59.47
そのAVX2命令の能力で高速に描画される動画を見て抜いてすっきりしなさい。
957デフォルトの名無しさん:2014/01/18(土) 09:45:04.14
俺もHaswell i7を尼でポチったからIntelから久しぶりに命令PDFでも落とすか
SSE2しか使ってなかったわ
958デフォルトの名無しさん:2014/01/18(土) 19:20:22.76
ML64.exeなんか勉強しないといけないな
めんどくさ('A`)
959デフォルトの名無しさん:2014/01/20(月) 17:04:34.14
AVX2は256bitを常に満たしつつ演算していかないと電力効率が悪そうだな。
ゲーム系の場合はSSE命令(intrinsic)をコンパイラが依存関係を調べて
自動的にAVX命令に変換してもらわないと、手作業で256bitを埋めるのは
しんどいだろう。
960デフォルトの名無しさん:2014/01/21(火) 20:38:18.85
内積の計算するのにSSE3から追加された_mm_hadd_psを使うより、以前の
3回_mm_shuffle_psしてから足すやつの方が速かった…(corei7)
SSE3はいらない子だったんだな、残念

しかしCPUはAVX2まで対応してるが、脳ミソをSSE4以降に対応させるのはしんどい…
961デフォルトの名無しさん:2014/01/22(水) 22:39:33.55
AVX2もたいして速くないね。
単にできるようになっただけ。
962,,・´∀`・,,)っ-○○○:2014/01/30(木) 09:00:19.41
>>960
内積演算するのになぜdppsを使わないの?
こっちも大して速くないけど。

ぶっちゃけると
struct { float X, float Y, float Z }ならX[8], Y[8], Z*[8]にパックしなおして
処理が終わったときに戻すようにすればいい。
そしたらvfmulps + vfmadd231ps + vfmadd231psの3命令で8並列処理できる。
963,,・´∀`・,,)っ-○○○:2014/01/30(木) 09:00:52.63
>>961
有効な使い方を知らないだけでは
964デフォルトの名無しさん:2014/01/30(木) 10:56:36.23
>>962
> 内積演算するのになぜdppsを使わないの?
dppsはSSE4の命令でまだ普及率を考えるとSSE2でいいやと思っただけ

> struct { float X, float Y, float Z }ならX[8], Y[8], Z*[8]にパックしなおして
それはAOS→SOAにしろって事だけど内積だけを8個以上のベクトルに適用する事がないな
大量の頂点をCPUで座標変換する時には間違いなくそうすべきだけど普通GPUでやる訳だし
965,,・´∀`・,,)っ-○○○:2014/01/30(木) 19:26:58.04
> dppsはSSE4の命令でまだ普及率を考えるとSSE2でいいやと思っただけ

SSE4対応のCPU普及率が低いなんて統計あったっけ?

複数バージョンの関数作ってCPUID見て分岐すりゃいいじゃん。
そこで妥協したら何のためにSIMD命令をわざわざ使ってるのという話になる

> それはAOS→SOAにしろって事だけど内積だけを8個以上のベクトルに適用する事がないな

別に内積「だけ」をSoAで処理してそれ以外をAoSで処理しなければならないなんて
ルールを作る必要ないよ。
966デフォルトの名無しさん:2014/01/30(木) 20:07:14.58
まーた都合のいい解釈が始まった
967デフォルトの名無しさん:2014/01/30(木) 22:19:58.67
>AOS→SOA
C++でオブジェクト指向でプログラム作ってるのに
こんな真似しなきゃならんとは
968デフォルトの名無しさん:2014/01/31(金) 01:21:27.44
>>967
SIMDを使うということは、低レベルのプログラミングになるのは当たり前。
オブジェクト指向ならストラテジでSIMDの詳細コードを書けばいいだけ。
969デフォルトの名無しさん:2014/01/31(金) 11:24:23.63
dppsよりmulps,addpsしたほうが速いからな
970デフォルトの名無しさん:2014/02/01(土) 00:50:14.71
以前ある処理をSIMD/マルチスレッドで高速化したことがあったが、同じ処理を
OpenCLで書いたらプログラムが格段に簡単になった上にさらに数10%速くなった。
イマドキのコンパイラに素人が挑んでも敵わんと実感したわ。
971デフォルトの名無しさん:2014/02/01(土) 07:59:21.45
OpenCLはCPUのコードでも速くなるのか。
ひょっとしてSIMD化までやってくれるのか??
972デフォルトの名無しさん:2014/02/01(土) 09:21:52.37
普通にやってくれる。もともとOpenCLはSIMD前提の規格だし、相性は悪くないんだろう。
あと、実行時にコンパイルするから実行環境に合わせた最適化ができるってのも大きいんだろうな。
973971:2014/02/01(土) 10:53:59.16
うお、AVX2とかも実行時コンパイルできるわけか!

今まではイントリンシックでのSIMD化が、コードの複雑さとパフォーマンスの最適点だと思ってたけど、
OpenCLがそこまでできるなら話が違ってくるな。

ちょっと触ってみるわ。
974デフォルトの名無しさん:2014/02/01(土) 11:43:54.28
選択肢は多数あるよな。
C++ AMPのサンプルなんて、CPU_C++ノーマルとCPU_AMP最適化では
21倍の差が出たよ。
975971:2014/02/01(土) 14:01:59.27
うん、GPU使うならC++AMPがいいな。
C++11の範囲内だけで書けるし、パフォもなかなか。
976デフォルトの名無しさん:2014/02/01(土) 16:59:56.12
OpenCLって文字列でコード埋め込むクソ仕様だろ
977デフォルトの名無しさん:2014/02/01(土) 17:25:20.88
そんな事言ったらOpenGLだってシェーダーは文字列でコードに埋め込む糞仕様だよ
普通は適当に暗号化してバイナリにくっつけてると思うが
978デフォルトの名無しさん:2014/02/01(土) 20:55:49.11
>dppsはSSE4の命令でまだ普及率を考えるとSSE2でいいやと思っただけ
SSE4.1って45nm Core2で使えるようになったと思ったから
5年以上たってると思うけど
979デフォルトの名無しさん:2014/02/01(土) 22:54:37.80
>>973
いまのOpenCLでCPUのコードが自前でSIMD化したものより速いんだったら、
SIMDのコードが糞だと思うよ。単純なベクトル化だけだったらインテル
コンパイラを使ったほうが幸せになれる。
980デフォルトの名無しさん:2014/02/01(土) 23:46:14.29
>>979
自動ベクタ化ではインテルの圧勝だけど、intrinsicsで書いてあればVCとほぼ互角な気がする
インテルが負けることも多いなぁ
981デフォルトの名無しさん:2014/02/02(日) 10:23:13.25
>>980
インテルコンパイラがVCと互角になるようなことって、
同じ条件で、計算でボトルネックになるところではは
ないと思うけどな。
982デフォルトの名無しさん:2014/02/02(日) 11:43:37.11
>>981
intrinsicsのSIMDコードが処理時間の多くを占めているので、
命令のスケジューリングではほぼ互角といってもいいと思います
983デフォルトの名無しさん:2014/02/02(日) 12:49:53.29
プログラマがSIMDの世話さえしてやれば、あとはVC++のコンパイラでも十分高速だと思うなぁ。
さすがにIntelプロセッサでIntelコンパイラには敵わないだろうけど、それでも差は1、2割とかじゃないの??
984デフォルトの名無しさん:2014/02/02(日) 13:23:36.03
>>979
ちなみにCPUで使えるOpenCL環境にはIntel製とAMD製があって、Intel CPUで動かした場合は
倍くらい性能が違った。
それぞれ自社のCPUに特化しているというのもあるんだろうが、やっぱりインテルのコンパイラは
この分野では優秀なんだろうな。
985デフォルトの名無しさん:2014/02/02(日) 23:08:42.52
intrinsicsで書かれたコードなのでレジスタのアロケーションと命令のスケジューリング
の比較と言っていいと思うけど、VCが勝つこともあるし差も僅かなのでほぼ互角としました

OpenCLは一応ベクタ化の工程があるからインテル製が強いんじゃないかなぁ
NECと提携してコンパイラの技術も向上してるのかな?
986,,・´∀`・,,)っ-○○○:2014/02/06(木) 21:31:22.45
あれは内部的にはSoAに変換して処理してる。

命令セット側が並列化用の高級言語に歩み寄ってる面もあるよ
AVXにはvblendvpsとかのプレディケート命令もあるしvgatherやvpermilpsで
効率的にAoS-SoA変換を行うことができる。

その辺の仕組みがわかった上で使う分にはいいよ
AVX-512ではSIMDレジスタが32本と8本(7本)マスクレジスタ
主要命令がプレディケーション対応になるからますます並列化言語が有利になる

少なくともこれからの時代は
「最新命令についてけないバカと老害にはSIMD化コードを触らせるな」
とはいえるかもしれない。
OpenCLで書かれたコードは実行時コンパイルだからランタイムさえ更新されれば
最新命令に追従できるからな。
987デフォルトの名無しさん:2014/02/06(木) 23:23:48.02
プレディケーションサポートはうれしいな。
今までガリガリ自分で書いてた。
988デフォルトの名無しさん:2014/02/07(金) 14:10:56.95
団子ちゃん今は派遣じゃないんだっけ?
989デフォルトの名無しさん:2014/02/07(金) 23:22:17.72
わざわざ「触らせるな」と言わんでも、素のSIMDコードを書くのはこの先
コンパイラ屋と組み込み屋と物好きだけになっていくだろうな。
990デフォルトの名無しさん:2014/02/08(土) 13:02:44.50
馬鹿に触らせるななんて
プログラムに限らず大昔からだよ
991,,・´∀`・,,)っ-○○○:2014/02/08(土) 16:36:42.86
戦時にもあったっけな
勤勉なバカが一番害悪だとか
992デフォルトの名無しさん:2014/02/08(土) 16:49:17.36
真面目系クズみたいなもんか
993デフォルトの名無しさん:2014/02/08(土) 17:07:09.31
ゼークト将軍ね。
994デフォルトの名無しさん:2014/02/08(土) 22:41:37.68
>>989
あと数値計算だな。
もっとも最近はGPUとかで、SIMDのコードすら書かなくなってきているけど。
995デフォルトの名無しさん:2014/02/08(土) 23:58:44.69
コンパイラが進歩してきてるから、数値計算やりたいだけの人は
SSEのような素のSIMDを扱う必要はなくなるって話だろ。
996デフォルトの名無しさん:2014/02/09(日) 12:30:14.54
SSE系SIMD拡張は、コンパイラの対応がクソすぎた
ヒープをアラインしたきゃ_aligned_malloc使えとか
自動ベクトル化〜♪とか
早くHSAとかに駆逐されるべき
997,,・´∀`・,,)っ-○○○:2014/02/09(日) 17:31:39.11
GPGPUはお膳立てがもっと面倒だぞ
998 忍法帖【Lv=40,xxxPT】(1+0:5) :2014/02/09(日) 23:32:42.16
次スレ

SSE AVXのプログラミング★2
http://toro.2ch.net/test/read.cgi/tech/1391956310/
999デフォルトの名無しさん:2014/02/10(月) 00:11:11.34
埋めましておめでとうございます!!!
1000デフォルトの名無しさん:2014/02/10(月) 00:16:40.46
SIMDは永久に不滅です!
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。