【C++】高速化手法【SSE】at TECH
【C++】高速化手法【SSE】 - 暇つぶし2ch1:デフォルトの名無しさん
05/10/27 02:55:36
C++やインラインアセンブラ、SSEなどによる高速化の手法
について語りましょう。

2:デフォルトの名無しさん
05/10/27 03:00:35
まずはi++は++iにしろよ。

3:デフォルトの名無しさん
05/10/27 03:02:26
それで速度があがるならな

4:デフォルトの名無しさん
05/10/27 03:07:02
Intelのコンパイラ買って開発したほうがいいんじゃね?
ヘタに素人が最適化なんてやるより

5:デフォルトの名無しさん
05/10/27 03:07:39
アルゴリズムよりメモリアクセスが最大のボトルネックだったりする。
結局レジスタやキャッシュを意識するのが重要になってくる。

6:デフォルトの名無しさん
05/10/27 03:09:50
>>4
コンパイラを変えるんじゃなくてパフォーマンスの解析ツールを
買わないとダメじゃないかな。
コンパイラ自体はVC7も用途によっては悪くないし。

7:デフォルトの名無しさん
05/10/27 03:14:21
>>6
VC++はプロファイラがついてると思うが

8:デフォルトの名無しさん
05/10/27 03:14:44
今月のCマガ買って読め。


9:デフォルトの名無しさん
05/10/27 03:21:52
STL使うなら自分で同じような物を作ったほうが高速。

10:デフォルトの名無しさん
05/10/27 03:24:25
その心は?

11:デフォルトの名無しさん
05/10/27 03:26:35
なんでいきなりSTLが・・・

12:デフォルトの名無しさん
05/10/27 04:41:40
主要部分をasmで書き直せばOK

13:デフォルトの名無しさん
05/10/27 05:59:50
>>7
VC++のプロファイラは、普通に一通りの機能を備えているのに、使われないんだよね。

VC.NET用だと、Compuware(Numega)がプロファイラを無償で提供してくれてるよ。
VC++6.0まで、TrueTimeは売り物だったのにねぇ。


14:デフォルトの名無しさん
05/10/27 06:01:00
>1
>>12

インラインアセンブラよりも、組込み関数を使ったほうがいいことが多い。
・コンパイラが最適化をしてくれる
・プログラムの記述が楽で、修正しやすい。
という2つの大きなメリットがあるよ。

15:デフォルトの名無しさん
05/10/27 06:01:56
なおVC系の場合、
組込み関数をインライン展開する
というオプションを有効にしてしまうと、
インライン展開されてしまい、最適化されない
という直感的ではない結果になるので、確認しながらやりましょう。

16:デフォルトの名無しさん
05/10/27 06:02:27
VCにプロファイラがあるなんて気づかなかった
というか2chで聞いたら無いっていわれてずっと信じてた

17:デフォルトの名無しさん
05/10/27 06:09:25
VC7でなくなったんだっけか

18:デフォルトの名無しさん
05/10/27 11:13:28
>>13
>使われないんだよね。
GUIに罠が仕掛けてあるからじゃまいか?

19:デフォルトの名無しさん
05/10/27 11:23:51
SSE2が付いてるマシンではインラインアセンブラで書かれた処理を実行したいけど、
それ以外のマシンでは普通のC++で書かれた処理を実行したいと言うような場合、
どうすればいい?

20:デフォルトの名無しさん
05/10/27 11:25:47
開始時に判別して関数ポインタで入れ替え

21:デフォルトの名無しさん
05/10/27 11:29:20
やっぱそれしかないか。
関数のインライン化されにくいなぁとか、
C++のメンバ関数だと面倒だなぁとか思ったんで。

22:デフォルトの名無しさん
05/10/27 12:25:13
>>21
インスタンスをやたら作る必要が無いならファクトリーパターンで作り分けしてもらうという逃げ方もある。


23:デフォルトの名無しさん
05/10/27 16:10:52
んなややこしいことしなくても、マクロ使って1つのソースから2つのオブジェクトを吐かせればいい。

関数ポインタだってコストかかるので、1つずつの関数を切り替えるのではなく、
2通りのプログラムを1つのプログラムに押し込むくらいの気持ちで、
もっとmain関数に近いところから切り替えてしまおう。

24:デフォルトの名無しさん
05/10/27 23:22:49
インテルコンパイラってプリフェッチ命令を挿入するとか言ってるけど
プリフェッチって入れても効果ほとんど無いよね?
あとこれからPen3コアをベースにしたCPUになっていくからPen4用に
最適化はしないほうがいい?

25:デフォルトの名無しさん
05/10/27 23:26:27
>>24
場合によるだろ。prefetch命令はL2へのロードのアルゴリズムを
変更するので、場合によってはメモリのレイテンシを劇的に減らす
事が出来る。というかintelのpdf嫁。

26:デフォルトの名無しさん
05/10/28 03:13:27
prefetch命令を使って具体的に速度改善を説明する本とかないのかな。
サンプルコードとか載せてるのがあったら欲しい。
Webでも以外と情報無いし。

27:デフォルトの名無しさん
05/10/31 20:11:01
STL like Template based coding with MMX/SSE extension
URLリンク(www.codeproject.com)

Intel IPP
Iten OpenCV
そのまま使えば高速じゃん


28:デフォルトの名無しさん
05/11/10 03:07:31
>>27
なんだこれ。
マトリクスとかImageとか扱えるものなのか。
結構みんな使ってるんだろーか。

29:デフォルトの名無しさん
05/11/10 05:49:34
クイックソート以外の例えばマージソートやバルブソートなどはどのようなときに使うのでしょうか?

30:デフォルトの名無しさん
05/11/10 07:43:42
>>29
クイックソートは万能ではない。
特にソートする要素数が少ないときには他の方法が早い。
また、安定でないという欠点もある。(マージソートは安定)

31:デフォルトの名無しさん
05/11/11 01:17:48
>>29じやないんだが
>また、安定でないという欠点もある。(マージソートは安定)

これどーゆー意味なんよ?
高速化のスレだから速度の事を言ってるのか?

32:デフォルトの名無しさん
05/11/11 01:53:10
>>31
ソートで不安定といったら
比較関数の評価で重みが重複した場合に順序関係が保存されない
ことだと思うが…(;´Д`)

33:デフォルトの名無しさん
05/11/11 07:49:51
>>31
>>31
>>31

34:デフォルトの名無しさん
05/11/11 13:33:13
出席番号順にソート済みの身体測定データを身長順にソートしたいとする。
ただし、同身長の人間がいる場合は出席番号の若い順に並んだままになっていて欲しい。
そういうときは「安定したソート」の出番よ。
クイックソートだと出席番号はバラバラになるからな。

まあ「安定した速度」って点でもマージソートはなかなかのもんだと思うけど
それにしても

35:デフォルトの名無しさん
05/11/11 13:36:35
それは、キーの指定が悪い。

36:デフォルトの名無しさん
05/11/11 13:47:58
>>31
基本情報の資格でも取ったほうがいいお
言葉が通じないと頭良くても吸収できないでしょ

37:デフォルトの名無しさん
05/11/11 20:59:00
>>35
ソートで大小の評価を、
身長だけではなく、出席番号も加味してやればいい
と言いたいのだろう。

でもね、出席番号がついてなかったら、どーするの?

38:デフォルトの名無しさん
05/11/12 02:14:44
一般的にソート前のインデックス順序を比較で使えばいい
二次キーとして出席番号があるならそれを使えばいいし

39:デフォルトの名無しさん
05/11/12 17:04:32
インデックスがついていなかったら?

40:デフォルトの名無しさん
05/11/12 18:46:58
アドレスで比較すればいいだろ馬鹿か?

41:デフォルトの名無しさん
05/11/13 16:52:40
アドレスで比較? なに馬鹿いってるの?

42:デフォルトの名無しさん
05/11/13 19:38:41
IntelのライブラリはAMDでワザと遅くなるようにしてそうなんで
一般向けには使ってません

43:デフォルトの名無しさん
05/11/14 02:57:33
高速なメモリコピーするにはmemcpy?
それともキャシュ無視するためにSSEとか利用するのか?

44:デフォルトの名無しさん
05/11/14 07:00:54
memcpyの実装はたくさんあるから一概には言えないぞ。

最もシンプルなのは1バイトずつコピーしているし、
コンパイラによってはインライン展開どころか組込み関数として処理しちゃうぞ。

45:43
05/11/15 02:12:42
へぇー、組み込み関数(SSE?)で処理しちゃうのか。
ネットで調べてたらSSEのレジスタ4つにまず読んで、それを
また4つ書き出すとレイテンシとやらを隠蔽できるとかなんとか
あったけどそんな感じかな。
とりあえずmemcpy使っておきます。

46:デフォルトの名無しさん
05/11/15 15:00:39
組込み関数の意味がわかってない希ガス。


47:デフォルトの名無しさん
05/11/15 17:17:53
関係ないけど __divdi3 は組み込み関数なんだろうか。

48:・∀・)っ-●◎○- ◆Pu/ODYSSEY
05/12/11 17:53:45
直にCPUの命令またはその組み合わせに展開してしまえる関数だね。

組み込み関数の利用は#pragma intrinsic で明示できるよ。
逆に出来ない場合は組み込み関数として用意されてないといえる。」



ぶっちゃけIntel C++のオートベクトライズなんてあんま役に立たない。
処理を並列化できるところは明示的にMMX/SSEの組み込み関数
使って最適化したほうがいい。
CPUの動きを知り尽くしてレジスタカラーリングしてくれるから
へたなアセンブリコード書くより速い。

あとIntel C++なんかは、インライン関数を基本的に展開しない。
STL使ったら重いってことは結構ある。
ただし __forceinliceは受け付ける。


VC2005はcpuidとかローテート命令まで組み込み関数として使える
ようになったから、アセンブラ嫌いにはかなりフレンドリーになった希ガス。

49:デフォルトの名無しさん
05/12/12 08:14:59
ローテートはVC6の頃から組み込み関数であった希ガス。

50:デフォルトの名無しさん
06/01/30 17:07:08
2005は8bit版や16bit版も用意されてる
URLリンク(msdn2.microsoft.com)(en-US,VS.80).aspx

51:デフォルトの名無しさん
06/02/13 23:04:16
                       ¦
                \     |
                  \   人  /
                    メ´  ヾ  _,-'
                 -―<  , -、 て_
        C++とSSE!      ) / / (´
                          / / ⌒ 、
                  (⌒V ,'´`ヽ
        ト、       ,ヘ   ヽ  !   :〉
        ト、ヽ    / /!    /   、゙ーァ'
        |,ノ ´ ̄` ヾ!  /   /`~´
        ,' >   < ゙, /   /
          l   、ー―:ァ  i/   /
          ゙、   Y⌒/  ,/   /
        `''ァ‐`ー'      /
         / i      /


52:デフォルトの名無しさん
06/02/14 09:28:47
だんごって何の仕事してんの?

53:デフォルトの名無しさん
06/02/14 17:36:10
.NEETでFA

54:デフォルトの名無しさん
06/02/17 12:53:20
倍精度実数、うらやましいなー

55:デフォルトの名無しさん
06/05/10 23:25:12
constで最適化が促進させられる理由ってなんでそ?

56:55
06/05/10 23:28:03
書き込むスレ間違えました。失礼しました。

57:デフォルトの名無しさん
06/06/03 15:41:51
[1] 授業単元: 数値計算法 
[2] 問題文(含コード&リンク): ①f (x) = cos (x) - x2 = 0 の根のうち、0 < x < 1 を満たすものを2分法で求める 
初期値 a, b が入力でき、 6桁推定された解と関数 f (x) を呼びだした回数を出力するようにしなさい。 
[3] 環境 
 [3.1] OS: WindowsXP 
 [3.2] コンパイラ名とバージョン: VC 6.0 
 [3.3] 言語: C 
[4] 期限: (2006年06月08日まで 

よろしくお願いします 


58:デフォルトの名無しさん
06/06/03 20:12:46
やべっ 二分法って何だっけ
忘れちゃったよ

59:デフォルトの名無しさん
06/06/03 21:02:27
>>58
カップラーメンを従来の1.5倍の速度で完成させる最適化技法

60:デフォルトの名無しさん
06/06/06 23:05:22
調理時間の短いラーメンほど短時間で伸びる

61:デフォルトの名無しさん
06/06/07 02:49:26
グルテンを加えるといい

62:デフォルトの名無しさん
06/06/08 20:36:36
麩になっちまう

63:デフォルトの名無しさん
06/06/11 01:52:05
即値で掛け算する場所を書き直してみたら?

64:デフォルトの名無しさん
06/06/11 13:36:33
PenMのSSE2って遅くね?

65:・∀・)っ-○◎● ◆toBASh....
06/06/11 14:11:11
デコーダがネック。複合デコーダパスだからね。
汎用&MMレジスタベース命令と交互に配置するとデコーダネックを隠蔽できる。

Yonahでは解消されてる。てかめちゃくちゃスループットいい

66:デフォルトの名無しさん
06/06/11 21:19:38
じゃあPenMだったら無条件でSSE2不使用、ってコーディングはもうしちゃ駄目だね。

67:デフォルトの名無しさん
06/06/12 05:21:20
そもそもYonahな時点でPenMじゃないし。
つかPenMって3年前から更新されてない一昔前のチップだろ。

68:デフォルトの名無しさん
06/06/12 05:50:51
ド忘れされてるDothanとi915萌え
YonahもBanias、Dothanと同様Pentium-Mですよ。
ただ発表後にPentiumブランド消失と絡んでIntel Coreとも名付けられちゃったが。
ブランド展開がまだよく分からんのでこの先どうなるか知らんが

69:デフォルトの名無しさん
06/06/12 23:51:39
面白い話題なんでもっと調べたいんですが、
いい本ないでしょうか?

やっぱりパターソン&ヘネシーですか?

70:デフォルトの名無しさん
06/06/20 21:14:25
メーカのドキュメント

71:デフォルトの名無しさん
06/10/12 18:47:05
SSEはコンパイラが自動的に使ってくれるのですか?

72:デフォルトの名無しさん
06/10/12 20:00:52
コンパイラによる。VCだとスカラ演算のみ。
自動ベクトル化が可能なコンパイラはgcc4.0系とかiccとかPGIとか。

73:デフォルトの名無しさん
06/10/20 02:49:00
SSEで最適化してもメモリアクセスのほうがボトルネックになんね?
キャッシュとかよく分かんねけどメモリよりキャッシュを意識せな
いかんのだろうけど。

74:デフォルトの名無しさん
06/10/20 03:06:04
処理の内容によるんじゃない?
動画の画像処理みたいにプリフェッチの予測が当たりやすい処理だと
メモリ帯域の方がボトルネックになってる感じはしない。
他の分野についてはわかりません。

75:デフォルトの名無しさん
06/10/20 03:50:56
>>73
同じデータを色々な組み合わせで何度も使う場合
キャッシュをうまく効かせるのが腕の見せ所。

76:デフォルトの名無しさん
06/10/20 09:13:41
誰かSSEのプリフェッチをどう使えばいいのかまとめてくれ。

77:デフォルトの名無しさん
06/10/20 14:58:09
めちゃくちゃ大雑把に話せば、
メモリを使う100クロック前くらいで
64byteごとに1回プリフェッチ命令を置く。
どの命令がいいかは、全部試して速いのを採用。

詳しくは、たくさんコードを書いてから
キャッシュについて勉強してくれ。
俺も勉強せねば・・・。

78:デフォルトの名無しさん
06/10/25 11:25:01
GPUと組み合わせ使うて場合って
GPUができる計算はみんななげちゃうって方針でいいの?

低次元行列計算はDirextXでできるみたいだから、
DirextXになげちゃおかと思ってるのだけど

79:デフォルトの名無しさん
06/10/26 03:45:06
>>78
DirectXは誰が動かしていると思っているの?
ユーザプロセスは?
OSカーネルは?

80:デフォルトの名無しさん
06/11/11 01:02:00
インテルのペンティアムプロセッサのマシン語で
高速化を勉強できる良い入門書みたいなのあったら教えてください
ホント、よろしくお願いします。
         
このとおり!m(_ _;)m m(-.-;)m m(_ _;)m

81:デフォルトの名無しさん
06/11/11 01:24:25
>>4

82:デフォルトの名無しさん
06/11/11 01:40:00
そうおっしゃらず。。
なにとぞ、お願いします~m(_ _;;)m

83:デフォルトの名無しさん
06/11/11 08:03:04
>>83
いやマジで、下手な本買うよりiccのアセンブラ出力眺めた方がよっぽど勉強になるって。

84:デフォルトの名無しさん
06/11/11 10:14:57
なるほど、そういう意味でしたか。

85:デフォルトの名無しさん
06/11/11 12:12:26
>>80
MMXテクノロジ最適化テクニック(ISBN4-7561-0797-4)の5章


86:80
06/11/11 22:35:35
>>85さん、ありがとうございます。
早速書店で探してみます。m(_ _)mペコリ

87: 【凶】 【488円】
07/01/01 10:52:18
SSEでどこか参考になるサイトはありませんか?


88:デフォルトの名無しさん
07/01/01 12:07:08
つ[google]

89:デフォルトの名無しさん
07/01/08 18:18:09
最近のコンパイラはSSEなどは指定しなくても自動的に使ってくれるのでしょうか?

90:デフォルトの名無しさん
07/01/08 18:30:46
ではまず最近のコンパイラの定義から(ry

91:デフォルトの名無しさん
07/01/08 18:32:37
>>89
そういうコンパイラもあります。

92:デフォルトの名無しさん
07/01/08 18:34:43
インテルコンパイラです

93:デフォルトの名無しさん
07/01/08 18:36:58
自動的に使うようになってると、SSEがないCPUでは動作しないのでは。

94:デフォルトの名無しさん
07/01/08 18:59:08
O3を指定した場合、自動的に検出され使われる

95:デフォルトの名無しさん
07/01/08 19:03:58
  _  ∩
( ゚∀゚)彡 オッサン!オッサン!
 ⊂彡

96:デフォルトの名無しさん
07/01/08 19:07:29
ここってこんなに人居たんだ

97:デフォルトの名無しさん
07/01/08 19:28:09
>>95
オマイの駄洒落のほうが・・

98:・∀・)っ-{}@{}@{}@
07/01/08 20:10:18
/Qx*とか/Qax*なしで使うことってあったっけ?
とりあえずboost:mt19937はICCのオートベクトライズでやたら速くなるが

99:デフォルトの名無しさん
07/01/08 20:31:21
Auto-vectorization in GCC
URLリンク(gcc.gnu.org)

100:デフォルトの名無しさん
07/01/08 20:47:28
AMD64向けだと強制的に使ってくれる。

自動ベクトル化は知らん。


101:サイザー専用JAVA演習場 その2
07/01/08 21:17:02
次スレまできた。飽きっぽい俺が良く続くもんだ。Σ(´∀`;)
どうぞよろしくお願いします。

102:デフォルトの名無しさん
07/01/29 08:23:39
URLリンク(www.intel.co.jp)
ここにあるインストラクションセット表って、
SSE3以降のものも載ってます?

103:デフォルトの名無しさん
07/02/07 20:57:03
SSE3は載ってたと思う。SSSE3は知らん

104:デフォルトの名無しさん
07/02/09 01:09:07
gcc 4.1.1をMinGW gcc 3.4でコンパイルして使っています。
自分の使っているCPU向けに最適化をしようと、
-O2 -march=pentium-m -msse2 -mfpmath=sse
上のオプションを付けてLame 3.97をコンパイルしたところ、最後の
-mfpmath=sse
を外した方が速いという結果になってしまいました。
CPUはCeleron Mを使っています。

Cerelon Mでは、実数演算ではSSEではなく80387を使った方が速いのでしょうか。
SSE命令を使った方が一見速そうに見えるのですが・・・。

105:・∀・)っ-○◎● ◆DanGorION6
07/02/10 01:07:28
BaniasかDothanかYonahかにもよるけど、SSEはあんまり得意じゃないよMは


106:104
07/02/10 16:29:40
>>105
Dothanコアです。

MはSSEが得意ではないのですね。参考になりました。
参考までに、姫野ベンチでも実験したところ、こちらは-mfpmath=sseありの方が速かったので、
コードに依るかも知れません。

107:・∀・)っ-○◎● ◆DanGorION6
07/02/10 21:00:29
Pentium M系アーキテクチャでSSE*が遅いのはデコーダがネックになってるらしい。
Complex Decoderのみでデコードされるから、倍精度は浮動小数が速くても不思議じゃない

Pentium MのFPUは加減算・乗算毎に倍精度×1、単精度×2だけど
x87とSSEスカラ演算だと単精度はクロックあたり1、SSEのパックド演算だと2つは
発行できるから、単精度ならまだ使う価値があるね。

108:デフォルトの名無しさん
07/02/10 21:59:57
演算ユニットの構成は

Port 0: x87ADD x87&SSE-MUL
Port 1: SSE-ADD(SP Only)

よってクロック毎に実行できる最大値は
x87-SP: 1
SSE-SP: 4
SSE-DP: 1

109:デフォルトの名無しさん
07/02/12 16:51:08
んでもSSE使うように最適化オプションつけた方が
遅くなるってのは不思議だよなぁ。
早くならないってことはあっても遅くなるってのはなぁ・・・
タスクスイッチのときにXMMレジスタも全部退避するようになるから?
そういやXMMレジスタまで対比するか否かってOSはどうやって知ってるの?

110:デフォルトの名無しさん
07/02/12 16:58:01
>>109
そもそも初期状態でFPUセットになっているのなら、SSEを使うだけで切り替えコストが発生する。

111:・∀・)っ-○◎● ◆DanGorION6
07/02/12 17:01:00
まあ、Complexデコーダパス命令だから、の一言なんだが
待避のオーバーヘッドなんてたかがしれてる



MXCSRレジスタってあるじゃん

112:・∀・)っ-○◎● ◆DanGorION6
07/02/12 17:01:45
>>110
それXMMレジスタじゃなくてMMレジスタの話では

113:デフォルトの名無しさん
07/02/12 17:41:09
でもSISDならデコードも速い。
単純にコンパイラが最適化しきれてないだけじゃないのか。
そもそも104氏が何の処理をさせてたのか書いてないから
イマイチ議論のしようがない気もする。

おそらく人間が書けばDothanでもSSEの方が速いとは思う。

114: ◆0uxK91AxII
07/02/12 21:16:30
>>109
>XMMレジスタまで対比するか否か
URLリンク(hira.main.jp)()%2Flinux2.6

115:・∀・)っ-○◎● ◆DanGorION6
07/02/17 17:12:17
Core 2 (Merom)ベースのCeleron Mももう出たし

116:デフォルトの名無しさん
07/02/19 20:47:39
二つの符号付及び符号無し 64bit 整数の乗算、
さらには 128bit 整数同士の乗算などは
SSE/SSE2/SSE3 命令群を使うことで高速化できるのでしょうか?

そもそもこれらの命令は SIMD 目的であって
ビット幅の長い演算が目的ではないので、
見当違いでしょうか?

117:・∀・)っ-○◎● ◆DanGorION6
07/02/20 00:30:25
64ビット同士の整数乗算は素直にx64命令セット使えと思うが。。。

16×16の積算・積和演算があるから組み合わせればいくらでも可能だ罠

118:デフォルトの名無しさん
07/02/21 14:03:24
海外旅行での現地のATMでのキャッシングって、
キャッシング枠ですか?それともショッピング枠ですか?
以前現金主義の友人がどうしても両替商見つからなくて
現地のATMでキャッシングしたら、日本に帰ってきて
ショッピングとして明細に出てたって聞いたんですが。

119:デフォルトの名無しさん
07/02/21 15:09:23
>>118
ATMによる。スレ違い。

120:デフォルトの名無しさん
07/02/25 13:31:40
誤爆じゃないのか

121:デフォルトの名無しさん
07/03/02 21:40:36
浮動小数点モデルを /fp:fast にする
精度は落ちるが

122:デフォルトの名無しさん
07/03/03 09:27:27
マルチタスク/マルチスレッドで、セマフォを長時間握ったまま返さない奴とか見つける、とかは
やっぱプロファイラとかで動的解析しないと分らんよね。
そんなの静的解析でどうにかなるもんじゃないか・・・。

123:デフォルトの名無しさん
07/06/04 18:02:04
doubleは2つ同時にしか実行できないのか?

124:デフォルトの名無しさん
07/06/04 18:08:28
>>123
日本語よろ!

125:デフォルトの名無しさん
07/06/04 18:54:23
だぶる先生らいふのことだろ。
常識的に考えて。

126:デフォルトの名無しさん
07/09/28 23:10:54
ダブル先(の)生ライフ?

127:デフォルトの名無しさん
07/10/01 19:33:27
>>123
C++でおk

128: ◆0uxK91AxII
07/10/01 23:04:52
>>123
一つのみも可。
ex) addsd

129:デフォルトの名無しさん
07/12/31 11:50:57
下がり過ぎ

130:デフォルトの名無しさん
08/11/08 21:50:37
SSEで大部分が記述された
正規表現エンジンって知りませんか?

131:デフォルトの名無しさん
08/11/09 00:12:17
闇雲にSSEを使えば速くなるってもんじゃないし、そんな阿呆な代物ないでしょ。
# 速度に寄与する肝腎な箇所に使っているってことなら話は別だが。

132:デフォルトの名無しさん
08/11/09 01:43:59
sseで正規表現・・・どこで使ったものやら

133:デフォルトの名無しさん
08/11/10 14:07:10
SSEって並列処理や積和なんかが1命令化で速くなる。
端からデータを舐めていくような処理はあまり効果ないよ。
特に検索には向かない。

134:デフォルトの名無しさん
08/11/10 14:17:20
bit列のマッチングはどう?
1bitずつずらしたのをxorしてall 0になったかどうか調べるとか

135:デフォルトの名無しさん
08/11/10 21:40:31
strlenをSSE2でやる人がいるくらいだし、その応用でstrchr/strstrのような単純な検索はできると思う。
ただ、正規表現となるとうまく使うのは難しいと思う。

136:デフォルトの名無しさん
08/11/18 03:23:27
sse4.2じゃないのか

137:,,・´∀`・,,)っ-●◎○
08/12/21 11:48:46
固定文字列部分を抽出してBoyer-Moore法とかで検索するのが良く使われる方法。
strstrなんかはSIMDを使った力技検索に置き換えることができる。

>>136
確かにあれは速いようだ


138:,,・´∀`・,,)っ-●◎○
08/12/21 11:51:30
固定文字列部分ならともかく「大部分」をSIMDに置き換えることに意味はない。
文字クラス程度ならSSE4.2で一括判定みたいなのも可能になるかと思うけど

139:デフォルトの名無しさん
08/12/21 12:13:43
つうかそんなのAltiVecでとうの昔にやられてる事だしな。
Intelは必要な命令(シャッフル、MIN/MAXなど)が揃うまでにどれだけかかるんだ。
ルーチンごとにSSE1があるか、2があるかと判定しなくちゃいけなくて面倒くさい。

140:,,・´∀`・,,)っ-●◎○
08/12/21 12:18:35
Macのこと言ってるのか?
SSE3以上使える前提できめうちで組めるからかえって楽だろw

大体にAltiVecに文字列比較命令なんてねーよ。
汎用レジスタ-SIMDレジスタ間のダイレクト転送命令ないし
レジスタ値を比較してbranchフラグを更新する命令もない。

そもそも更新が停まってるだけだろ。

141:,,・´∀`・,,)っ-●◎○
08/12/21 12:30:26
SSE2の16バイト単位の文字列同時比較なんてこれだけだぞ
(MMX(SSE)での8バイト同時比較でもこいつの64bit版を使えばいい)
pcmpeqb → pmovmskb → test → branch

SSE4.1だと
pcmpeqb→ptest→branchでおk


AltiVecだとpmovmskb相当のことをMSBの縮約いちいちマスク&シフトを繰り返した上
いったんメモリにストアしてから汎用レジスタで読み直さないといけない。
pmovmskbなんてIntelプロセッサでは1サイクルでこなせる処理だがAltiVecなんて
ここだけで何十サイクルもかかる。

なにかと俺がコケにしてるCell SPEのほうがまだ使えるよ。
SPUにはMSBじゃなくてLSBのビット縮約命令がある。

要するに
AltiVec=保守されてない時代遅れの命令セット
俺も使ってたからよくわかるよ。

142:,,・´∀`・,,)っ-●◎○
08/12/21 12:47:01
俺の経験上文字列サーチでAltiVec使うと遅くなるケースのほうが多い。
だからMacOSでもstrcpy/memcpyみたいな分岐の必要ない操作に限ってだけAltiVecが内部的に使われてる。

143:デフォルトの名無しさん
08/12/21 13:31:59
同時比較でいいならロードして比較してvec_all_eq()するだけじゃね?
ストアと読み出しはいらん。

144:,,・´∀`・,,)っ-○◎●
08/12/21 18:51:16
>vec_all_eq()
あのさー、それ複合関数だから。

ではマスク生成+縮約+ストア+汎用レジスタにロードって操作を1つの組込関数に纏めただけ。
1インストラクションで済んでるわけではない。

アセンブリコード読んだことある?無いだろうけど。


CPUネイティブのベクトル比較命令であるvcmpequb自体は、SIMDレジスタ上にマスクを生成するのみ。
マッチしたのか、マッチしてないのか、マッチした場合、どこの位置でマッチしたのかっていう判定は
汎用レジスタ側でやるしかないんだよ。

145:デフォルトの名無しさん
08/12/21 19:51:08
お前こそvcmpequbの仕様を読んだ事あるのかと。

> The CR6 is set according to whether all, some, or none of the elements compare equal.

146:デフォルトの名無しさん
08/12/21 19:59:03
最近論調がおとなしくなってきて改心したのかと思えば、
内心人を見下してるのは変わってないんだよな。

147:デフォルトの名無しさん
08/12/21 20:04:05
あ、なんでアセンブリコードとか的外れな事言ってるのかようやく分かった。
最適化オプションを全く指定しないと確かに複合になるね。

ていうかさあ、デバッグ用とはいえ確かにこのアセンブリは変態だけど
つまりはお前は大口たたいておきながら
その実>>143を言われて顔真っ赤にして焦ってアセンブリ出力を確認したんだろ。
恥ずかしいなあ。

148:,,・´∀`・,,)っ-○◎●
08/12/21 20:06:12
「.」付き版はcr6を更新するからptest相当のことだけはできるよ。それは正しい。
どこでマッチしたかを求めるには汎用レジスタ側でやんないといけない。

pmovmskb相当の命令がないから遅いんだって。
Cell SPEだと7ビットシフトしてギャザリングし、ビットスキャンすれば位置が求まるけど


149:,,・´∀`・,,)っ-○◎●
08/12/21 20:07:28
>>147
で、pmovmskbの代用命令はどこにあるの?


150:デフォルトの名無しさん
08/12/21 20:08:21
っヒント:もうL1に乗ってる

151:デフォルトの名無しさん
08/12/21 20:09:45
>>149
無いよ。
そこを叩きたいなら叩いてくれ。

152:,,・´∀`・,,)っ-○◎●
08/12/21 20:11:31
そんなことは聞いてない。
SSE*にはSIMDレジスタ上のベクトルデータのMSBを縮約してダイレクトに汎用レジスタに転送する命令がある。
bsfと組み合わせればマッチ位置まで簡単に求めることができる。

AltiVecには、そういう命令は、ない。

153:,,・´∀`・,,)っ-○◎●
08/12/21 20:12:47
>>151
なら結局遅いじゃん。

154:デフォルトの名無しさん
08/12/21 20:15:38
支離滅裂だな。
それが初めから分かってるなら慌ててアセンブリ確認なんてしてないだろ。
百歩譲って今お前が力説したい事にスポットを当てるなら
all_xx()が複合であるかどうかなんてどうでもいいんだからな。

ていうかstrchなのかstrstrなのかハッキリしろよ。
反論するのに都合の良い方を選択してるだけじゃねーか。

155:,,・´∀`・,,)っ-○◎●
08/12/21 20:16:13
慌ても確認もしてないよ

156:デフォルトの名無しさん
08/12/21 20:17:49
じゃあall_xxが複合だと言ったのはどこのだれですか?
結局gather出来ないんだから、そこはどうでもいいんだけどね。

157:,,・´∀`・,,)っ-○◎●
08/12/21 20:19:12
>>154
どっちもSSEより遅いよ。

PPCからの移植にSSE1まで使えるか2まで使えるかとか気にしなきゃいけないと思う方が馬鹿だよ。
Win32でもSSE2が使えないCPUなんてどのみちSIMDユニットの実装もショボイから最適化対象としては無視して良いくらいだよ。
非SIMDのパスに飛ばしておけばいい。


158:デフォルトの名無しさん
08/12/21 20:22:57
まあそれも論点ずれてるんだが、建設的な話をしたいからお前に合わせよう。

確かにSSE2が使えないCPUは大抵しょぼいから無視しても良いんじゃないかな。
強いて言うならAMD(笑)が例外だが。

でもx86陣営がそういう路線を歩んでいるのは間違いなくて
SSE3, SSSE3, SSE4.1, SSE4.2, AVX, LNIといちいちチェックしなくてはいけない日々が続く事には変わりない。

159:デフォルトの名無しさん
08/12/22 00:20:05
Core2 Duoと比較して、Athlon X2がそれほど酷いとは思えないんだけど。

160:デフォルトの名無しさん
08/12/22 00:39:51
整数演算はひどいな

161:デフォルトの名無しさん
08/12/22 12:59:27
一晩考えて、何故団子がgatherに必死なのかが分かった。
団子はトリップ検索が主だから検索対象が極端に小さくて、
詳細な位置の特定の方がボトルネックになっているんだな。

162:,,・´∀`・,,)っ-○◎●
08/12/22 18:05:57
tawake

163:デフォルトの名無しさん
08/12/22 18:42:38
続きをどうぞ

164:デフォルトの名無しさん
08/12/23 01:34:18
>>161
誰が笑いを取れとw

165:デフォルトの名無しさん
08/12/24 07:45:53
変な事言った?

166:,,・´∀`・,,)っ-○◎●
08/12/24 19:00:25
一晩考えることじゃないだろ。俺のブログ一通り読んだら30分以内に否定される。

167:デフォルトの名無しさん
08/12/24 20:19:04
で?

168:,,・´∀`・,,)っ-○◎●
08/12/24 20:52:06
笑いしかとれなかったね

169:デフォルトの名無しさん
08/12/24 23:46:08
そうだね。俺もだけど団子も痛い子だね。

170:デフォルトの名無しさん
08/12/25 00:24:23
痛いのはお前だけですからwww

171:デフォルトの名無しさん
08/12/25 00:39:33
だから何故?
煽ってるんじゃなくて純粋に。

172:デフォルトの名無しさん
08/12/26 19:45:57
無知のまま過ごすのは恥だし勿体ないので団子でも名無しでも回答くれないかな。
名無しが答えられるかどうかは疑問だけど。

173:デフォルトの名無しさん
08/12/26 20:29:55
        ∩___∩
. \     | ノ      ヽ
   \  /  ●   ● |
     \|    ( _●_)  ミ  そんなエサでおれが釣られるかクマー!
      彡、   |∪| ,/..
       ヽ   ヽ丿/  /⌒|
       / \__ノ゙_/  /  =====
      〈          _ノ  ====
       \ \_    \
        \___)     \   ======   (´⌒
           \   ___ \__  (´⌒;;(´⌒;;
             \___)___)(´;;⌒  (´⌒;;  ズザザザ


174:デフォルトの名無しさん
08/12/27 07:45:25
都合が悪くなるとすぐ逃げるか話そらすからな。
結局161が図星だったのか。

175:デフォルトの名無しさん
08/12/27 10:20:33
名無しが寂しそうにしてるから構ってやれよw

176:デフォルトの名無しさん
09/01/04 11:41:54
ビット演算の代数的な性質、それを導き出す公理が知りたい
算術演算から式変形だけでアセンブリ言語のコードを導き出せるようになりたい

177:デフォルトの名無しさん
09/01/04 12:31:09
コンパイラでも作りたいの?

178:デフォルトの名無しさん
09/01/07 23:00:55
メモリアクセスとかを考慮すると構造体より配列のほうが高速?

179:デフォルトの名無しさん
09/01/08 00:02:43
>>178
同じ。

180:デフォルトの名無しさん
09/01/08 00:13:42
SSE2でnビット左rolってどうやって記述すればいいのですか?

181:デフォルトの名無しさん
09/01/08 00:34:34
Intelのマニュアル読みなさい

182:,,・´∀`・,,)っ-○◎●
09/01/08 08:10:02
好きなの使え

;;【16bit×4並列】
movdqa xmm1, xmm0
psllw xmm0, N
psrlw xmm1, 16-N
pand xmm0, xmm1

;;【32bit×4並列】
movdqa xmm1, xmm0
pslld xmm0, N
psrld xmm1, 32-N
pand xmm0, xmm1

;;【64bit×2並列】
movdqa xmm1, xmm0
pslld xmm0, N
psrld xmm1, 64-N
pand xmm0, xmm1

【↓こっからまだ存在してないCPU向け】
protb xmm0, xmm0, N ;; 8bit×16用 AMD SSE5
protw xmm0, xmm0, N ;; 16bit×8用 AMD SSE5
protd xmm0, xmm0, N ;; 32bit×4用 AMD SSE5
protq xmm0, xmm0, N ;; 64bit×2用 AMD SSE5
あと要素毎に変量が変えられる命令もサポートされてる。
俺は実用性を思いつかないが何かしら使える用途があるんだろう。

ちなみに128ビットフルは、場合によるので省略する。
4バイト単位ならpshufdとかのシャッフル命令使った方がいい。

183:デフォルトの名無しさん
09/01/08 11:55:57
俺の質問には答えずに人の質問には答えるんだな。

要素ごとのは、例えば最上位に立っているビットからNビット欲しいとか色々使い道はあるよ。
floorみたいのを自力で実装しようとすれば分かる。

184:,,・´∀`・,,)っ-○◎●
09/01/08 12:46:20
サーセンwwwpandじゃなくてporだwww

185:デフォルトの名無しさん
09/01/09 14:29:17
>>179
うほ?
>>178の意味がいまいち分からんが、
char array[0x100];

struct{char value;} array[0x100];
だったらレジスタサイズにパディングされる分、構造体の方が早くね?
ちなみに、同じ事だが容量気にして構造体のなかでshortとか使うと
パデイング入るんでメモリに無駄が発生する。
まぁ、パディングを知っていれば無駄を防ぐこともできるけど。

186:デフォルトの名無しさん
09/01/10 05:48:58
構造体にすればパディングされると決まっているわけではない。
だからその例だけだとどちらとも言えない訳だが。

構造体のメンバを一部だけshortにするのは意味が殆どない(寧ろ遅くなる)という点については同意。

187:デフォルトの名無しさん
09/01/11 01:26:48
>>185

short array[3];

struct{short value1;short value2;short value3;} array;
でどっちが高速かという意味です。

188:デフォルトの名無しさん
09/01/11 01:44:37
配列のindexが定数なら変わらんだろ
アセンブラ見ろ

189:デフォルトの名無しさん
09/01/11 01:50:19
>>185
> struct{char value;} array[0x100];
> だったらレジスタサイズにパディングされる分、構造体の方が早くね?

pragmaやattributeでパックしない限りpaddingは入らないだろ。

190:,,・´∀`・,,)っ-●◎○
09/01/11 06:03:24
16とか32になるのはいいけどメモリアドレッシングで使えるscaleが8倍までなんだよな。
添字によるアクセスは思わぬ性能低下を起こすことがある

191:,,・´∀`・,,)っ-●◎○
09/01/11 06:05:36
>>189
構造体やその配列の場合、パディングが入る。
デフォルトが4バイト単位だったかな?

192:デフォルトの名無しさん
09/01/11 10:18:30
おまえほんとにだんごか?
デフォルトなんて決まってるわけ無いだろ

193:,,・´∀`・,,)っ-●◎○
09/01/11 10:25:51
まあデフォルト値は処理系依存だな。

>>189の言ってることが嘘ってことで。
少なくともパディングが入らない保障はない。

194:デフォルトの名無しさん
09/01/11 10:51:19
コンパイラ依存だよな。
歴史的な理由で当時の最長のレジスタがdoubleだからCPUのアライメントが8byte推奨で、コンパイラも8byteに詰めてた気が。
もしかしたらx86じゃなくてPowerPCかも知れん。

195:デフォルトの名無しさん
09/01/11 14:47:57
VCやGCC辺りはパディングが入る。
Bitmapヘッダをそのまま構造体で読み取ろうとして引っかかった
やつも少なくない筈。(VCならpragmaを使えばパディングを消すことができる)
一応32bitCPUならVC、GCC共にcharもshortも32bitで確保される。
64bitなら64bitで確保されるとか聞いたことがあるが真偽は不明。
蛇足だが、VCでchar array[5];などと確保すると確保した容量+3
の領域が確保される。

196:デフォルトの名無しさん
09/01/11 15:41:20
URLリンク(kikyou.info)
> つまり最大でポインタ二つ分のデータを保持しています。LP64の場合は128bitとなります。ILP32の場合は64bitとはならず、パディングの関係でLP64と同じく128bitとなります。
8byte?

197:デフォルトの名無しさん
09/01/11 15:44:14
将来AVXの1024bit SIMDが使えるようになった際に、128byteにパディングされるとかなるとイヤだな。
その頃にはメモリは数十GBで128byteなんてゴミみたいなもんだろうけど。

198:,,・´∀`・,,)っ-○◎●
09/01/11 15:47:54
その頃までにSIB.scaleのビット拡張してほしいね。1ビット増やせばx16, x32, x64, x128になるのに。

199:デフォルトの名無しさん
09/01/11 15:59:23
\  \\       ____         // / /
<           _-=≡:: ;;   ヾ\            >
<         /          ヾ:::\           >
<         |            |::::::|          >
<        ミ|-=≡、 ミ≡==- 、 |;;;;;/          >
<         || <・>| ̄| <・> |─ /\         >
<         |ヽ_/  \_/    > /         >
<        / /(    )\      |_/          >
<        | |  ` ´        ) |           >
<        | \/ヽ/\_/  /  |           >
<        \ \ ̄ ̄ /ヽ  /  /           >
<          \  ̄ ̄   /  /       \    >
  / /        ̄ ̄ ̄ ̄ ̄ ̄ ̄     \\ \ \
     ___
   / ―\ ナンミョウホウレンゲッキョウナンミョウホウレンゲッキョウナンミョウホウレンゲッキョウ
 /ノ  (@)\ ナンミョウホウレンゲッキョウナンミョウホウレンゲッキョウナンミョウホウレンゲッキ
.| (@)   ⌒)\ ナンミョウホウレンゲッキョウナンミョウホウレンゲッキョウナンミョウホウレンゲッ
.|   (__ノ ̄|  |   ///;ト,  ナンミョウホウレンゲッキョウナンミョウホウレンゲッキョウナンミョ
 \   |_/  / ////゙l゙l;  ナンミョウホウレンゲッキョウナンミョウホウレンゲッキョウナンミョ
   \     _ノ   l   .i .! |  ナンミョウホウレンゲッキョウナンミョウホウレンゲッキョウナンミョ
   /´     `\ │   | .|  ナンミョウホウレンゲッキョウナンミョウホウレンゲッキョウナンミョ
    |       | {   .ノ.ノ  ナンミョウホウレンゲッキョウナンミョウホウレンゲッキョウナンミョ
    |       |../   / . ナンミョウホウレンゲッキョウ


200:デフォルトの名無しさん
09/01/12 00:40:28
パディングってむやみに入れるとキャッシュヒット率悪くなってかえって効率落ちたりしないんだろか


201:,,・´∀`・,,)っ-●◎○
09/01/12 00:42:04
逆にキャッシュラインを跨ぐと効率悪くなるんだよ


202:デフォルトの名無しさん
09/01/12 00:44:50
>>200-201
どっちも一般論だー

場合によるでしょ

203:デフォルトの名無しさん
09/01/12 00:58:25
実測すれば済む話

204:デフォルトの名無しさん
09/01/12 01:11:32
>>191
cygwin上のgccで試してみたけど、padding入らないよ

205:デフォルトの名無しさん
09/01/12 13:59:38
>>204
CPUによるが
struct foo {
char a;
double b;
};
でパディングが入らなかったら例外起きるだろうが。

206:デフォルトの名無しさん
09/01/12 14:41:55
起こんねーよ、CPUによるが。

207:デフォルトの名無しさん
09/01/12 14:55:43
struct {char a, b, c;}だったらパディングなくても例外起きないよ。
コンパイラがまともなら。

208:,,・´∀`・,,)っ-○◎●
09/01/12 17:32:33
アラインメント制約の厳しいプロセッサなら、例外が起きないようにコンパイラが勝手にパディングするんじゃないかな。


しかしミスアラインメントのデータに対するロード・ストアの扱いは各CPUアーキ毎に方針が違ってて面白いな
x86のSSE以降は、ミスアラインメントを許すが遅い命令と、許さないが高速な命令の2通りを用意。
対して、POWER/CellのSIMDは下位ビットを無視してロードし、プログラマが勝手にPermuteしてくれっていう扱い。

209:デフォルトの名無しさん
09/01/12 18:31:15
下位ビットを無視してくれるのはわざわざAND取ってアライメントする必要がないから楽でいいよな。

210:デフォルトの名無しさん
09/01/12 18:38:09
中を作る側もデコーダが軽くなるからウマー


211:デフォルトの名無しさん
09/01/13 01:17:59
>>205
> >>204
> CPUによるが
> struct foo {
> char a;
> double b;
> };
> でパディングが入らなかったら例外起きるだろうが。

なぜ勝手にdoubleが入ってるんだww
誰もそんな場合の話はしていない。
団子にこんな基本的なことで嘘つき呼ばわりされたが嘘じゃないってことで

>>185
> struct{char value;} array[0x100];

212:デフォルトの名無しさん
09/01/13 01:46:59
ところでパディングの入らない環境ってどんな環境だろ?
PC用で32bitプロセッサじゃ大抵入ると思うが。
sizeof(struct{char value;})==4
見たいにね。

213:デフォルトの名無しさん
09/01/13 02:10:47
struct{char value;} array[0x100];
printf("%d\n", sizeof(array));
=> 256
gcc-4.3.2ではこうなったけど、パディングってそもそも何だ?無効領域?

214:デフォルトの名無しさん
09/01/13 02:48:14
>>212
Crayだとchar=short=int=32bitとかが普通らしい。
PC用じゃないけど。

215:デフォルトの名無しさん
09/01/13 17:31:55
>>213
ゴメン
sizeof(struct{char value;})じゃ1だね。
sizeof(struct{char v1;short v2})じゃ4になったから試さずに
書いちゃった。メンバーが同じサイズなら配列化されるっぽいね。

216:デフォルトの名無しさん
09/01/13 19:04:45
1つの構造体中でサイズ違いのアクセスが発生するかどうかによって変わるのじゃない。
連続の同一単位アクセスだけなら必要ないし、むしろ最適化にも邪魔だと思うんだよね?

struct{char a;} arrayo[10];
struct{char a; char b;} arrayp[10];
struct{char a; char b; char c;} arrayq[10];
struct{char a; int b;} arrayr[10]; /* inserted */
struct{int a; char b;} arrays[10]; /* interted */

217:,,・´∀`・,,)っ-○◎●
09/01/13 21:09:54
俺的に配列は__declspec(align(32))がデフォです

218:デフォルトの名無しさん
09/01/13 21:34:41
32?
16じゃないのか?

219:,,・´∀`・,,)っ-○◎●
09/01/13 23:06:38
AVX化を視野に入れてるから

220:デフォルトの名無しさん
09/01/14 08:14:08
Alphaには16bitレジスタなかったよん

221:デフォルトの名無しさん
09/04/07 23:53:51
MacでIntel PPC両対応のコードを書いています。

SSEでは、16ビット整数や8ビット整数をVectorに一括セットする命令が
見つけられません。
SSEで、以下のAltivecと同等の記述をするには通常どのような手順を使えば
よいのでしょうか?

例:Altive用コード
vUInt8 multiL, multiS;
vUInt16 shift;
switch (mode) {
case 2:
multiL = vec_splat_u8(5); multiS = vec_splat_u8(3); shift = vec_splat_u16(3);
break;
case 1:
multiL = vec_splat_u8(3); multiS = vec_splat_u8(1); shift = vec_splat_u16(2);
:

222:デフォルトの名無しさん
09/04/08 00:08:13
っ _mm_set1_pi16

223:デフォルトの名無しさん
09/04/08 05:32:21
>>222
__mm_set1_pi16とか_mm_set1_pi8とかですと、MMXレジスタが対象と
ありました。

SSEレジスタにセットする場合、もしかして次のような手順になるのですか?
 CPUでメモリ上にパターンを作成
 SSEレジスタにロード

それとも、そもそもsseレジスタを使うのが遠回りで、MMXレジスタで2回
まわすのが普通なのでしょうか?

224:デフォルトの名無しさん
09/04/08 07:20:56
「e」pi16だな。

225:デフォルトの名無しさん
09/04/08 20:22:07
>>224
なるほど!
__m128i _mm_set1_epi8(char b)

見落としていました。ありがとうございました。

226: ◆0uxK91AxII
09/04/09 17:01:19
xrgbxrgb の8[Byte]を、vuyyの4[Byte]に変換する場合、
途中で、
mm0: 左右平均r, 左右平均r, 左r, 右r
mm1: 左右平均g, 左右平均g, 左g, 右g
mm2: 左右平均b, 左右平均b, 左b, 右b
っていう感じに並べ換えるのに、えらく時間が掛かる。

32[bit]なOS上で、Athlon 64の2[GHz]、SSEは2までを使用、
メモリは、DDR 400を、dualchannel、
連続した1024*768[dot]の処理に、6[ms]弱を要する。

極力、同じレジスタに連続して触れないように書こうとしても、
何かとやりづらい。

他に適当な方法があれば、教えて欲しいとか、書いてみる。

227:デフォルトの名無しさん
09/04/09 21:58:05
pmaddwd 2個で済むように書けるよな?

228: ◆0uxK91AxII
09/04/09 23:29:25
thx
pmaddwd - packssdw - pmaddwdで、vuかyyの二要素出せるのかー。
/(^o^)\

229: ◆0uxK91AxII
09/04/10 01:48:24
5[ms]弱に短縮。
適当に並び換えれば、もう少し行けるかも。

230:デフォルトの名無しさん
09/04/14 08:19:33
バイト列の入れ替えをしたいのですが、普通はどのように行うのでしょうか。

単に偶数、奇数バイトをスワップさせたいだけなのです。
00 11 22 33 00 11 22 33 00 11 22 33 00 11 22 33
11 00 33 22 11 00 33 22 11 00 33 22 11 00 33 22

上マスク、下マスクで二つの値を出し、それぞれシフトして、ANDを取る
という方法しか思いつきません。もっと賢い方法がありそうな気がします・・・

231:デフォルトの名無しさん
09/04/14 09:36:53
4バイトならbswapで一発なんだが

232:デフォルトの名無しさん
09/04/14 10:05:56
言葉足らずですみません。xmmでの処理途中なんです。


233:デフォルトの名無しさん
09/04/14 13:25:24
psrlw psllw por
または
pshufb
あたりじゃね?

>>231
エンディアン変換命令使ってどうするw

234:デフォルトの名無しさん
09/04/15 23:05:41
>>233
なるほど、前者はSSE2までのマスク+シフト+orですね。
後者はSSSE3ってことはCore2Duo以降ですか・・・

CoreDuo以前を切り捨てれば楽だけど・・・ん~。

235:,,・´∀`・,,)っ-@{}@{}@{}-
09/04/16 08:01:14
2通りの関数書いてCPUIDで振り分けるのはどう?
SSSE3でも128ビット版は65nm版Core2やAtomは速くないよ。
ちなみにSSE5なら
protw xmm0,xmm0,8
で1命令ですな

236:デフォルトの名無しさん
09/04/16 14:44:26
>>235
>2通りの関数書いてCPUIDで振り分けるのはどう?
これでやってみます。サンクスでした。

237:デフォルトの名無しさん
09/04/18 11:46:24
お前ら、ちょっと頼みがあるんだが。
SSEでどの程度高速化できるか、ちょっくら試しにコードを書いてみたんだが全然速くねぇ。
コードの書き方が悪いのか、俺のPCのCPUがAthlonなのが悪いのか、アドバイスおくれ。

ソースはコレ↓
URLリンク(uproda11.2ch-library.com)

題材はビットカウントで、コンパイラは GNU C++。

よろしくおながいします。





238:デフォルトの名無しさん
09/04/18 11:47:42
あ、言い忘れたけどDLキーはデフォルトの1です。


239:237=238
09/04/18 11:50:15
ちなみに家のPCでの実行結果はこんな感じ

init data
func = reference : test=OK : clock = 15063 : sum = 504854834
func = bit32 : test=OK : clock = 6812 : sum = 504854834
func = bit64 : test=OK : clock = 5219 : sum = 504854834
func = sse : test=OK : clock = 5109 : sum = 504854834

240:デフォルトの名無しさん
09/04/18 12:06:54
すまん、データの初期化でバグがあった。

直したんで、こっち↓を見てくれ。
URLリンク(uproda11.2ch-library.com)


241:デフォルトの名無しさん
09/04/18 12:36:15
生のアセンブラで書けよ!インラインってw
実行せずとも分かる事を述べよう。
ソースを16バイトアライメントに合わせている?
ソフトウェアパイプライン化が行われていない。(これをやっていないとSSEの意味がない。)
そもそも速度計測しているコードが小さい。
SSE4.2だと1命令でなかった?

242:デフォルトの名無しさん
09/04/18 13:17:12
>>235
CPUIDで振り分けてもSSE5じゃ使えるCPUが現状ないジャマイカw
SSEPlusでエミュレーションするとSSE2の実装で9.3サイクルかかるな。
これ分岐いらんだろjk
URLリンク(sseplus.sourceforge.net)

243:デフォルトの名無しさん
09/04/18 20:12:39
勉強し始めです。
リトルエンディアンとxmmで混乱してしまったので教えてください。

実アドレス上、以下の順で並んでいたアドレス上のデータは、
0 1 2 ... D E F
xmmレジスタにロードすると
F E D ... 2 1 0
の順で取り込まれるのですよね?

_mm_srli_si128()で1バイト右シフト(256で割る)するとレジスタ上は
0 F E ... 3 2 1
となり、これをメモリにストアすると
1 2 3 ... E F 0
という順でストアされる

ということは、
 xmmで右シフトした状態というのは、
 メモリ上では(上記表現では)左シフトした状態に相当
これ、認識あっていますでしょうか。

244:デフォルトの名無しさん
09/04/18 21:25:00
デバッガで見えるレジスタの状態は右が下位だよっと
糞長い128bit変数だと思えばいいよ

245:,,・´∀`・,,)っ-○◎○
09/04/19 01:13:42
>>240

inline __m128i population_count_sse_iter(__m128i *v)
{
__m128i tmp0,tmp1,tmp2,mask;
tmp0=_mm_load_si128(v);

mask=_mm_set1_epi32(0x55555555);
tmp1=_mm_and_si128(tmp0,mask);
tmp2=_mm_srai_epi32(tmp0,1);
tmp2=_mm_and_si128(tmp2,mask);
tmp0=_mm_add_epi32(tmp1,tmp2);

mask=_mm_set1_epi32(0x33333333);
tmp1=_mm_and_si128(tmp0,mask);
tmp2=_mm_srai_epi32(tmp0,2);
tmp2=_mm_and_si128(tmp2,mask);
tmp0=_mm_add_epi32(tmp1,tmp2);

mask=_mm_set1_epi32(0x0f0f0f0f);
tmp1=_mm_and_si128(tmp0,mask);
tmp2=_mm_srai_epi32(tmp0,4);
tmp2=_mm_and_si128(tmp2,mask);
tmp0=_mm_add_epi32(tmp1,tmp2);

mask = _mm_setzero_si128();
tmp0 = _mm_sad_epu8(tmp0, mask);
return tmp0;
}


246:,,・´∀`・,,)っ-○○○
09/04/19 01:17:51
【続き】
virtual int population_count(unsigned int data[4])
{
__m128i sum = population_count_sse_iter((__m128i *)data);
return _mm_extract_epi16(sum, 4) + _mm_cvtsi128_si32(sum);
}

virtual int population_count_array(unsigned int data[][4],int size)
{
__m128i sum = _mm_setzero_si128();
for(int i=0;i<size;i++)
{
sum = _mm_add_epi32(sum, population_count_sse_iter((__m128i*)data[i]));
}
return _mm_cvtsi128_si32(sum) + _mm_cvtsi128_si32(_mm_srli_si128(sum, 4));
}

んで、うちの環境ではこんな感じになった(Core 2 Duo E8500, Cygwin)

func = reference : test=OK : clock = 8890 : sum = 504854834
func = bit32 : test=OK : clock = 4859 : sum = 504854834
func = bit64 : test=OK : clock = 12829 : sum = 504854834
func = sse : test=OK : clock = 2156 : sum = 504854834
func = dango-sse : test=OK : clock = 1281 : sum = 504854834
func = dango-ssse3 : test=OK : clock = 1093 : sum = 504854834

64bitが遅いのは32ビットとしてビルドしてるからだと思うが、それはさておき
SSSE3を使う方法は、Penryn/Nehalemでは速いけど
AtomとかCore 2 65nm系は使えてもSSE2のより遅い。


247:,,・´∀`・,,)っ-○○○
09/04/19 01:18:54
virtual int population_count_array(unsigned int data[][4],int size)
{
__m128i sum = _mm_setzero_si128();
for(int i=0;i<size;i++)
{
sum = _mm_add_epi32(sum, population_count_sse_iter((__m128i*)data[i]));
}
return _mm_cvtsi128_si32(sum) + _mm_cvtsi128_si32(_mm_srli_si128(sum, 4));
}

訂正してくだしあ><

248:,,・´∀`・,,)っ-○○○
09/04/19 01:20:10
【これが正解】
virtual int population_count_array(unsigned int data[][4],int size)
{
__m128i sum = _mm_setzero_si128();
for(int i=0;i<size;i++)
{
sum = _mm_add_epi32(sum, population_count_sse_iter((__m128i*)data[i]));
}
return _mm_cvtsi128_si32(sum) + _mm_cvtsi128_si32(_mm_srli_si128(sum, 8));
}

249:240
09/04/19 06:24:28
>>,,・´∀`・,,)っ-○○○

うちのAthlonの環境でも>>246のdango-sseの結果と大体同じくらいの性能うpが確認できました。
しかし、こんなに差がつくとはSSE侮りがたし。

団子さん、多謝です!



250:デフォルトの名無しさん
09/04/25 20:53:10
VC++ と gcc (言語は C++)のインラインアセンブラで
SSE の16バイトアラインメントされていることを仮定した命令を使いたいのですが、
float の配列変数全体を16バイト境界にアラインさせることって可能ですか?

251:デフォルトの名無しさん
09/04/25 21:04:42
>>250
__declspec(align(16))と__attribute__((aligned(16)))
マクロなりなんなりで切り替えればいい

252:デフォルトの名無しさん
09/04/25 21:27:17
>>251
即レスありがとうございます!

253:,,・´∀`・,,)っ-○○○
09/04/26 01:00:01
__m128(あるいはその配列)との共用体にすれば勝手に合うけどね。


254:デフォルトの名無しさん
09/04/26 01:02:51
gcc で使えるの?

255:デフォルトの名無しさん
09/04/26 02:32:21
gcc で使えるの?

256:デフォルトの名無しさん
09/04/26 09:52:02
大事な事なので2回聞きました

257:デフォルトの名無しさん
09/04/26 15:03:36
#include <xmmintrin.h>

258:,,・´∀`・,,)っ-○○○
09/04/26 15:14:47
あとコンパイルオプションにフラグつけとけ
-msse

とか

259:デフォルトの名無しさん
09/04/26 15:23:18
そしてautotools地獄へ…

260:,,・´∀`・,,)っ-○○○
09/04/26 15:50:01
ああ、あのへんマジで何とかして欲しい。
Win32ではASMで書いた関数の頭にアンスコ付けないと認識しなかったりとか

261:デフォルトの名無しさん
09/04/26 18:46:23
頭に…アンスコ…?

262:デフォルトの名無しさん
09/04/26 18:53:03
アンダースコート被るんだよ

263: ◆0uxK91AxII
09/04/26 19:14:57
underscore、呼出規約云々のアレ。

264:,,・´∀`・,,)っ-○○○
09/04/26 21:11:39
こやつらには5Fhって言った方がわかりやすいかもしれんな


265:デフォルトの名無しさん
09/04/26 21:44:35
プログラマのくせに、「あんすこ」が通じないのはおかしい。

266:デフォルトの名無しさん
09/04/26 21:46:17
職業プログラマだけじゃないだろ
趣味でやるやつもいる

267:デフォルトの名無しさん
09/04/26 22:06:11
趣味グラマだけど理解してるよ


268:デフォルトの名無しさん
09/04/26 22:58:53
アンダーバーとか言う奴は素人

269:デフォルトの名無しさん
09/04/28 14:56:39
ひゃっひゃっひゃっひゃっ

270:デフォルトの名無しさん
09/04/28 16:21:42
なさけなや


271:デフォルトの名無しさん
09/04/28 17:08:11
アンダーバー。

272:デフォルトの名無しさん
09/05/01 21:18:18
今のVCのコンパイラは、インラインアセンブラを書くと、そのインラインアセンブラを含む関数が最適化がされないらしいけど、
xmmintrin.hなどは、使うと最適化されなくなる?

273:デフォルトの名無しさん
09/05/01 21:26:48
うん

274:デフォルトの名無しさん
09/05/01 21:45:13
インラインアセンブラだけインライン関数で分離すればいいじゃまいか

275:デフォルトの名無しさん
09/05/01 21:46:51
インライン展開されたら最適化抑制も伝播したりして。


276:デフォルトの名無しさん
09/05/01 22:26:45
>>273
いやいや、組込関数ならインラインアセンブラと違って最適化できるという触れ込みではなかったっけ?

277:デフォルトの名無しさん
09/05/01 22:33:02
sse使って、まだコンパイラが入り込むある余地があるのか?

278:デフォルトの名無しさん
09/05/01 22:37:15
xmmintrin.hなどの場合はxmmレジスタへの割付が最適化まかせなので、
最適化をしないと、1命令ごとにメモリとデータをやり取りするので非常に遅くなる。


279:デフォルトの名無しさん
09/05/01 22:41:37
__m128iってクラスはレジスタ的なもので局所変数にしか使えないかと思ってたんだが、
実はvector<__m128i> みたいな使い方もありなの?


280:デフォルトの名無しさん
09/05/01 22:45:35
typedef union __declspec(intrin_type) _CRT_ALIGN(16) __m128 {
     float               m128_f32[4];
     unsigned __int64    m128_u64[2];
     __int8              m128_i8[16];
    : 略
 } __m128;

てな感じで普通にメモリ上にとられるよ。最適化でレジスタに置きっぱなしになる。

281:279
09/05/01 22:54:29
そうなのか。ありがとう。


282:デフォルトの名無しさん
09/05/01 23:33:29
組み込み関数の最適化は
lstファイルでも出力して見てみるといいよ。
一応されるようだよ。

283:,,・´∀`・,,)っ-○○○
09/05/01 23:35:01
GCCはpshufb周りのコード生成が酷い。


284:デフォルトの名無しさん
09/05/01 23:36:16
まあgccはコードジェネレーター部がx86決め打ちじゃなくて汎用だからな

285:,,・´∀`・,,)っ-○○○
09/05/01 23:48:38
_mm_set1_epi8()相当のことやろうとしたんだけどさ
_mm_shuffle_epi8(_mm_cvtsi32_si128((int)c), _mm_setzero_si128());

ってやるじゃん。Intel先生は当然のごとくこういう風に生成するだろ。

pxor xmm0, xmm0
movd xmm1, DWORD PTR [esp+4]
pshufb xmm1, xmm0

3行で済むことを6行もかける馬鹿コンパイラ

pxor xmm0, xmm0
movd xmm1, DWORD PTR [esp+4]
movss xmm0, xmm1
pxor xmm1, xmm1
pshufb xmm0, xmm1
movdqa xmm1, xmm0

飽くまでカンだけど、pshufbの引数の順番間違えてて、応急処置的に直したんじゃないかと思うんだ

286:デフォルトの名無しさん
09/05/02 01:55:20
そういうときはgccのソース読むのが基本だろ。

287:,,・´∀`・,,)っ-○○○
09/05/04 14:47:39
insn-attrtab.cが酷いな。SSSE3以降の命令の扱いがテキトーすぐる。

288:,,・´∀`・,,)っ-○○○
09/05/04 17:26:36
>>279
処理系によっては自作アロケータで128ビットアラインされた領域に確保するようにしないと酷いことになるかもしれません。

289:デフォルトの名無しさん
09/05/04 21:03:31
GCCはGPLなんだから文句ばっかり行ってないでお前らも
プロジェクトに参加して改良しろよ

290:,,・´∀`・,,)っ-○○○
09/05/04 21:09:55
それは本末転倒。アセンブラよりも作業効率を期待してCコンパイラで生成できないか試みてるのに
いっそう手間かけてどうすんだと。別にGCCである必要ないんだよ。
っていうかオープンソース界隈は今頃AMD SSE5がキャンセルで大荒れだと思う。

291:デフォルトの名無しさん
09/05/04 21:36:28
まあ、正論だな

292:デフォルトの名無しさん
09/05/04 22:21:05
ダンゴさんの正論でスレがピリッと引き締まったな。

293:デフォルトの名無しさん
09/05/04 22:51:03
キャンセルって何の事って調べたら・・・
俺的にはAVX一本のほうが楽でいいな。AMDは正しい判断をしたと思う。
当初の予定はSSSE3もSSE4もサポートせずに、SSE5追加だけだったよね?

294:,,・´∀`・,,)っ-○○○
09/05/04 22:54:08
いや、元々SSSE3はSSE5と一緒に追加、SSE4.1/4.2は順次対応する予定だったと思う

295:デフォルトの名無しさん
09/05/05 21:04:42
Intel様、3Dゲームとか画像とか動画エンコとか特殊な用途向けよりもっと一般人が
恩恵をうけれるような命令を追加して下さい。といいつつ、マイナーな事言いますが、
IEEE754Rで改訂された10進浮動小数点の命令を追加して下さい。


296:,,・´∀`・,,)っ-○○○
09/05/05 21:10:40
一般用途とかけ離れてるだろ10進浮動小数なんて

金融演算でもやるのか?

297:デフォルトの名無しさん
09/05/05 21:38:01
>>296
そうです、金融がらみとかです。

298:デフォルトの名無しさん
09/05/06 20:28:58
>>290-292
一度実装すれば以後恩恵を受けられるわけだし、そもそもサポート契約してないなら、正論とは言えないだろう。

299:,,・´∀`・,,)っ-○○○
09/05/07 01:20:09
本来そういうのはハードベンダーが技術協力名目でやるものだろう

300:デフォルトの名無しさん
09/05/07 01:49:26
インテル様はインテル・コンパイラを買えと仰っているからなぁ。

gccのauthorに-○○○@2ch.netとでも付け加えた方が
トータルで安く上がるだろ。


301:,,・´∀`・,,)っ-○○○
09/05/07 02:06:08
Intelコンパイラもたいがいだよ。
_mm_set1_epi8()はCore 2以降でなら>>285の実装のほうが速いのに
-QxSSE4.1とか加えても使ってくれないのはどうしたものかね

_mm_set1_epi1(0)を pxor (_mm_setzero_si128()相当)に置き換えるのはさすがにやってくる

302:デフォルトの名無しさん
09/05/08 06:17:11
メディアンフィルタの高速なアルゴリズムを教えてください。
複数のピクセルから中央値を選べばいいだけなのですが、
ifステートメントを避けて並列化する方法はないでしょうか?

303:デフォルトの名無しさん
09/05/08 07:32:50
それを考えるのが面白いところなのに・・・

304:,,・´∀`・,,)っ-○○○
09/05/08 20:51:11
URLリンク(www.j-tokkyo.com)

特許申請されてるお

305:,,・´∀`・,,)っ-○○○
09/05/08 21:27:34
ちなみに言うと8要素のソートして真ん中の値をとればいいだけ。
pmaxub/pminubを使うことで大小入れ替えができる

ちょっと考えてみたが愚直な並列バブルソートでpmaxub/pminubを合計40回程度かな?
それでも1要素あたりにすると2.5回の比較で済む。
まあ、ベクトルのセットアップがちょっとばかし大変だが。

306:デフォルトの名無しさん
09/05/10 00:07:29
8?

307:,,・´∀`・,,)っ-○○○
09/05/10 00:25:33
自身含めて9か。
すまん素で間違えた

3.5命令・・・うーん

308:デフォルトの名無しさん
09/05/10 11:17:30
ダンゴさん何者なんだw CPUに詳しいな。

309:デフォルトの名無しさん
09/05/10 12:49:10
ダンゴさんへの賞賛でスレがヒートアップしたな

310:デフォルトの名無しさん
09/05/10 16:54:52
AGIストールとかパイプリングストールとか意味がわかりまセンチ

311:,,・´∀`・,,)っ-○○○
09/05/11 21:36:15
だんごー
だんごー

312:デフォルトの名無しさん
09/05/11 21:54:38
だんごー
だんごー
だんごー大家z(ry

だんごさんって鳥の方の人かしら。
もしそうだとすると、数年前に某荒板でCPUのこととかお話した元コテですがお久しぶりです(´・ω・`)ノ
人違いだったらごみんなさい。

313:,,・´∀`・,,)っ-○○○
09/05/11 21:58:28
島は鳥の左側です。

314:デフォルトの名無しさん
09/05/11 22:15:09
レフトシフト

315:デフォルトの名無しさん
09/05/12 12:56:48
おまえらだんごさんがいるうちにいっぱいためになる話聞いておけよ。


316: ◆0uxK91AxII
09/05/12 20:00:05
いっぱいだめになる話?

317:デフォルトの名無しさん
09/07/11 00:34:33
itoaを高速に書く場合
どうやってかけばいいのですか?

val % 10なんかで基数割してると
遅くてダメポなんですが.......

318:デフォルトの名無しさん
09/07/11 01:17:42
除算が遅いなら0.1を乗算すりゃいいじゃない

319:デフォルトの名無しさん
09/07/13 07:47:59
100でやれば除算回数が半分になる

320:デフォルトの名無しさん
09/07/13 10:41:55
テーブル引け

321:デフォルトの名無しさん
09/07/15 21:23:00
,,・´∀`・,,)っ-○○○先生
おられませんかー?

322:デフォルトの名無しさん
09/07/16 00:33:39
>>317
一体何桁の数字を変換したいんだ?
速くしたけりゃベクトル化すればいいだろ。

323:デフォルトの名無しさん
09/07/16 00:41:13
>>322
10桁っす

324:デフォルトの名無しさん
09/07/16 23:15:35
fbstpとか
10桁は遅いか

325:デフォルトの名無しさん
09/07/17 01:49:04
いっそ数値の方をBCDにしちまえ
ついでにCPUを6502にだな

326:デフォルトの名無しさん
09/07/17 02:15:08
10桁の数字を何回処理してどの程度時間がかかり、
どれだけ高速化したいのか位は言えよ。

327:デフォルトの名無しさん
09/07/18 18:37:21
fildしてfbstpするのが速そうではあるね

328: ◆0uxK91AxII
09/07/18 21:15:36
基数は可変...っと。
ふつーitoaの高速化は無意味。

329:デフォルトの名無しさん
09/07/18 21:35:05
> 基数は可変...っと。
それitoaじゃねー。

330:,,・´∀`・,,)っ-○○○
09/07/31 20:55:39
x86のAAMとかAADの基数って変えられたよな?
Opcodeがないからマシンコード直打ちになるけど

331:デフォルトの名無しさん
09/08/27 19:59:33
if (a>=b) a = 0;
これから条件分岐を取り除くにはどうすれば良いですか

332:デフォルトの名無しさん
09/08/27 21:32:22
(void)(a >= b) && (a = 0));

333:デフォルトの名無しさん
09/08/27 21:33:42
余計な括弧がついていた
(void)(a >= b && (a = 0));

334:デフォルトの名無しさん
09/08/27 21:50:02
それってアセンブラレベルでは分岐してないか?

335:デフォルトの名無しさん
09/08/27 21:54:03
アセンブラ以前に分岐しとるがな
if構文を使ってないだけでしかない

336:,,・´∀`・,,)っ-○○○
09/08/27 22:50:17
なぜ条件分岐を取り除きたいの?

倍精度・スカラだとこんな感じ

movsd xmm1, dword ptr [b]
movsd xmm0, dword ptr [a]
cmpgtsd xmm1, xmm0
andpd xmm0, xmm1
movsd dword ptr [a] xmm0

で、もっとも移植性の高く速いコードを生成する可能性の高い俺の回答はこれ。
a = (a >= b)? 0 : a;

っていうかConditional MOVEとかプレディケートの仕組みをハード的にサポートしてるCPUでないと
根本的に高速化にならないと思うんだ。
なんのために分岐を除去するのか、本末転倒な解決策でもいいなら、他にいくらでも方法はある。



337:デフォルトの名無しさん
09/08/27 23:53:51
つーか三項演算子ってもともとハードがサポートしてるから、それを利用する為に作られたってどこかで読んだような。
x86がサポートし始めたのがC言語の登場に比べれば割と最近だからまるで最新技術のような錯覚を覚えるけどな。

338:,,・´∀`・,,)っ-○○○
09/08/28 01:14:14
Pentium Proが出た時期を最近とか言っちゃうか?
それを最近って言っちゃうならRISCでプレディケートをサポートするCPUはかなり新しい部類だよだよ。
分岐のオーバーヘッドを軽減するための機構が必要になったのはパイプラインが深いCPUが出だした頃の話だからな。
分岐(条件ジャンプ)が相対的にボトルネックになったのが動機。



つーか、Pentium Proの更に10年前、386の頃からCコンパイラはあったろ?



あと、こんなブログ見つけた
URLリンク(keisanki.at.webry.info)

これARMそのまんまだな

339:デフォルトの名無しさん
09/08/28 01:22:30
Conditional MOVEで思い出したけど、cmovcなどのフラグレジスタを見るものは、前の演算結果が出るまでストールするから、普通に条件分岐するより遅くなることが多いって本当?

340:,,・´∀`・,,)っ-○○○
09/08/28 01:41:24
>>339
大嘘

>前の演算結果が出るまでストールする

これは大いなるミスリード。
CMOV命令の結果に依存しない命令は先行実行出来るだろ?
パイプラインの充填率を高める努力を怠ってはならない

>普通に条件分岐するより遅くなることが多いって本当?

分岐予測の精度と頻度によってはそうなる「こともある」程度
一般的には単純な3項演算に展開出来る程度の条件分岐ならCMOVのほうが速い


341:デフォルトの名無しさん
09/08/28 01:48:24
そうだったのか
サンクス

342:,,・´∀`・,,)っ-○○○
09/08/28 01:50:23
if - else のブロック中の演算式がいくつもあるようなのをcmovに展開して速くなるかって話なら
流石に無理。そういうイチャモン付ける奴は単に使い分けを見誤ってるだけ。

343:デフォルトの名無しさん
09/08/28 03:35:55
a &= - (a >= b);

344:デフォルトの名無しさん
09/08/28 03:37:43
あ、条件が逆だた

345:デフォルトの名無しさん
09/08/28 12:36:47
>>343
どういう命令に展開されるか意識して書いてる?
cond?0:1が表記上省略されてるだけで、大概のCPUでは演算回数は増えてしまうと思われ

条件フラグ値を汎用レジスタに転送する命令があればそれを使うんだろうが、
それなら既にConditional-MOVEより条件は悪い

フラグ確定までフラグに依存関係のある命令は(投機)実行できないのは同じだからな

346:デフォルトの名無しさん
09/08/28 16:30:21
だったら、最初のままでCMOVに展開されるから、何もしないでよい
で終了するだけじゃん。

コンパイラ次第だけど。

347:デフォルトの名無しさん
09/08/28 16:35:24
あ、比較とandの場合は
(cmp xx,xx)の後、
sbb edx, edx
and eax, edx
の2命令。

cmov の場合も
即値が使えないから、メモリアクセスをしないよう
比較の前にレジスタクリアをしなきゃいけないし
xor edx, edx
(cmp xx,xx)
cmovxx eax, edx
の2命令。

348:デフォルトの名無しさん
09/08/28 18:58:47
cmp->sbb->andで依存関係が生じる。

cmovはというと、P6以降のアーキではxorによるゼロクリアはALUを消費せず
リザベーションにゼロを入れるだけの操作にデコードされるから
実質cmp+cmovの2命令分のコストだけだな

349:デフォルトの名無しさん
09/08/28 19:13:14
そう言えばcmovを吐くコンパイラって見た事ないな
大抵前者のコードを吐く

350:,,・´∀`・,,)っ-○○○
09/08/28 19:34:15
単純にターゲットCPUがi386になってるからだろ。


351:デフォルトの名無しさん
09/08/28 20:33:40
cmp+cmovにもマクロフュージョン効けばいいのに

352:デフォルトの名無しさん
09/08/28 20:42:30
setccは普通に見るな

353:デフォルトの名無しさん
09/08/28 20:46:10
げっごめんageになってた

354:デフォルトの名無しさん
09/08/28 22:12:40
setccとcmovの違いが分からない

355:デフォルトの名無しさん
09/08/28 22:25:02
>>348
ただ、その分レジスタを消費するけどな。
内部的なレジスタリネーミングという話でなく、
アクセス可能なレジスタが足りずに内容を退避する必要が出て来るケースもある。

また、単純な比較命令ではなくサブルーチンコール等をまたぐ場合
フラグ保持のためにxor等でのクリアは使えない。
比較の後にmovで0を入れる等だと、「ゼロクリア時の特別扱い」の利点が弱くなる。

あと、当然だがcmovはP6以降。
まあこれは現在は問題にならないかもしれないけどね。

356:デフォルトの名無しさん
09/08/28 23:02:06
>>354
Intelが配布してるPDF見ればいいじゃん
cmovは条件が一致した時にソースをディスティネーションに転送する
setccは条件が一致した時にレジスタを1に設定、それ以外は0に設定する

C言語の場合条件は0か1で判定できるのでsetccで十分な場合が多い
但しcmov使った方がより短縮できる事もある

357:,,・´∀`・,,)っ-○○○
09/08/28 23:10:08
>>355
どんだけカツカツなんだよ

XMMレジスタにでも退避しろやwww

358:デフォルトの名無しさん
09/08/31 23:22:06
ダンゴさんって何者なんだw

359:デフォルトの名無しさん
09/09/08 18:49:43
このダンゴって本物のダンゴなの?
i5ってどうなのーって聞いてみたいんだけど。

360:デフォルトの名無しさん
09/09/08 20:07:19
だんごじゃないけどi5はi5だよ。それ以上でもそれ以下でもない。

361:デフォルトの名無しさん
09/09/08 20:13:34
>>360
おめーみたいなカスには聞いとらん失せろゴミが
ダンゴさんマダー?

362:,,・´∀`・,,)っ-○○○
09/09/08 20:47:27
i7にしろや

363:デフォルトの名無しさん
09/09/08 21:25:40
>>361
ちょwだれww
ほれ、なんかcore2の時とかこれはいいぜーとかなんか詳しく言ってたような気がしたから
i7なりi5なりのアーキテクチャ面からの意見を聞いてみたかったんだ

364:,,・´∀`・,,)っ-○○○
09/09/08 21:36:21
Phenom 2も悪くないCPUだから好きなの選べ。


365:デフォルトの名無しさん
09/09/09 02:09:19
>>363
i7ー900はメモリ周りが速い。(トリプルチャネル)
i5/i7(デュアルチャネル)で少し遅い。でもCore2よりは速い。
さあ選べ。


366:デフォルトの名無しさん
09/09/09 02:24:23
でもこれから6コアとか8コアとか12コアとか出てくるんだろ
少しでもFSBが速くないともっさりしてくるのは確実

367:デフォルトの名無しさん
09/09/09 02:33:02
>>365
Core2とi7を比較すると、とりあえずメモリが速いのと、デュアルコア*2からクアッドコアになったという利点が
あるのはわかる
i5はコア間でのやりとりがずいぶん遅いらしいので、場面によっては結構な影響を与えそう

iシリーズになって各命令が要するクロックとかパイプライン周りは変わってないの?

368:デフォルトの名無しさん
09/09/09 03:50:34
>>367
>iシリーズになって各命令が要するクロックとかパイプライン周りは変わってないの?
そのあたりは余り変わっていないと思われるが、大きく変わっているのはSSE4.2?(4.3だったか?)になっている。
メモリ周りと、キャッシュ周りが大きく変わっているので、iシリーズ用に最適化すると早くなるかもしれない。
iシリーズはQPIが速いので、Core2シリーズよりマルチプロセッサになったとき速い。
いずれにしてもメモリ帯域がボトルネックになりそうなプログラムを書くなら、
iシリーズを使った方がパフォーマンスが出る。
キャッシュに収まるレベルで、SSEの新機能を使わなければあまり変わらない。
今からならCore2Quadよりもi5の方がいいと思う。



369:デフォルトの名無しさん
09/09/09 04:17:10
i7って64bit時のパフォーマンスはどうなの?Core2より良いという話を聞くけど。

370:デフォルトの名無しさん
09/09/09 06:03:53
良いと言われる理由は、Core 2と違ってMacro-Op Fusionが64ビットでも使えることだったと思う。

371:デフォルトの名無しさん
09/09/09 17:21:56
2のx乗(xはfloat、絶対値が100未満)を、テーブル参照やFPUなしで、SSEで4並列処理できませんか?
精度は6bit程度で十分なんですが

372:デフォルトの名無しさん
09/09/09 20:19:58
無理ぽ

373:デフォルトの名無しさん
09/09/09 20:23:04
URLリンク(jrfonseca.blogspot.com)

374:,,・´∀`・,,)っ-○○○
09/09/09 22:32:19
整数乗なら簡単
指数部に加算するだけですむからな

375:デフォルトの名無しさん
09/09/09 22:51:39
お前ら文盲か?
可能なら方法を書け。
できないならできないと書く。
わからないなら黙って首吊って死ね。

376:デフォルトの名無しさん
09/09/09 22:56:14
で、それは4並列可能なの?

377:,,・´∀`・,,)っ-○○○
09/09/09 23:12:26
整数+小数点以下にわけて

整数部は指数部直接操作
あと小数点以下はpshufbで勝つる

378:デフォルトの名無しさん
09/09/09 23:19:12
釣りにすらならねえ。。。

379:デフォルトの名無しさん
09/09/10 00:03:24
>>373
これ凄いですね
VS2005では_mm_castがないようなので、*(__m128i*)&に直してコンパイルを通しました
自前で用意した64kBのテーブルがばっさり不要になりました
log10を求める処理もあるので、log2のソースと底の変換を使うことでこのテーブルもなくなりました
書き忘れでSSE2までという条件がありましたが、これも満たしていました
完璧です。ありがとうございました

380:デフォルトの名無しさん
09/09/10 00:11:34
あれ。Debugだと上手くいきますが、Releaseだと0とか負の無限大になってしまいますね
直接アセンブラに落として使います

381:デフォルトの名無しさん
09/09/10 00:34:34
連カキ失礼します
Releaseだと、__m128への代入の時点でスタックが何バイトがずれるようです
この後でカウンタを1加算する処理がありますが、0に1を足して1になるはずが-2になっていてびっくりしました
_m128をグローバル変数に置いたら直ったので、とりあえずこれで誤魔化します

382:デフォルトの名無しさん
09/09/10 00:35:11
おい!テーブル使わん言ったじゃねえかよ。死ねカス。

383:デフォルトの名無しさん
09/09/10 01:30:43
>>382
>>373
> Polynomial

384:デフォルトの名無しさん
09/09/10 08:35:36
>>382は本当にカスだな

385:デフォルトの名無しさん
09/09/11 01:21:58
>>382
テーブルと多項式の比較だから、下の方を見てみよう。


386:デフォルトの名無しさん
09/10/08 03:31:44
頻繁に整数を6で割った余りを使うプログラムなんですが、
除算が1回40クロック以上もかかると聞いて以下のようなロジック組んでみました。
試してみると若干早くなってるような気もしますが、
これは効率的って言えますかね?

387:デフォルトの名無しさん
09/10/08 03:33:43
unsigned int mod6(unsigned int m){
unsigned int a = 0;
static unsigned int x[] = {0,2,4,0,2,4,0,2,4,0,2,4,0,2,4,0,2,4,0,2,4,0,2,4};
__asm{
mov eax, m
test eax, 1
jz Mod3
inc a
Mod3:
shr eax, 1
lea ebx, x
mov edx, eax
and eax, 0000ffffh
shr edx, 16
add eax, edx
mov edx, eax
and eax, 0000003fh
mov ecx, edx
and edx, 00000fffh
shr ecx, 12
shr edx, 6
add eax, ecx
add eax, edx
mov edx, eax
and eax, 0000000fh
shr edx, 4
add eax, edx
mov edx, x[eax*4]
add a, edx
}
return a;
}

388:デフォルトの名無しさん
09/10/08 03:38:11
条件分岐入れるくらいなら素直に割れ。

389:デフォルトの名無しさん
09/10/08 03:47:13
考え方としては、偶数ビットシフトしても3で割った余りは変わらない
(ただしシフトして消える部分に立ってるビットがない場合のみ)のを利用します。

まず2の剰余を取った後、値を半分にして6の剰余から3の剰余の問題に変えます。
上位16ビットと下位16ビットを加算して17ビットに落とし、
6ビット/6ビット/5ビットに分割して加算して8ビットに落とし、
上位4ビットと下位4ビットに分割して加算して5ビットに落とし、
最後にテーブル参照して、その時点の3の剰余の2倍の値に変換して
最初の2で割った余りを足します。

390:デフォルトの名無しさん
09/10/08 03:59:17
>>388
条件分岐ダメですか?

もう一個レジスタ使って

mov edi, eax
and edi, 00000001h



add edx, edi
mov a, edx

ってやり方にもできますが。

391:デフォルトの名無しさん
09/10/08 04:44:47
x[]を読みに行く方が遅い説

392:デフォルトの名無しさん
09/10/08 07:17:20
・6割り算は本当にボトルネックか。
他にどうしようもなく遅い処理があるなら6割り算は無視していいはず。
6割り算だけする関数を作ってそれを呼ぶようにし、インライン展開を抑制してプロファイルを取るくらいはすべき。

・6割り算の代わりに6掛け算は使えないか。
つまり、データの持ち方を工夫して高速化したい処理全体で6で割った商と余りを利用するようにすれば割り算は無視できるはず。
余りも要らないなら、メモリコストも増えないだろう。

・値域はどのくらいか。配列参照で代用できないか。
値域が16ビット程度なら高高数十キロのメモリしか使わないで実現できる。巧くキャッシュに乗れば、速いかもしれない。

393:デフォルトの名無しさん
09/10/08 08:35:44
実に適切なレスだな、感動した

394:デフォルトの名無しさん
09/10/08 09:07:56
結論

人間よりコンパイラの方が賢い

395:デフォルトの名無しさん
09/10/08 09:18:27
コンパイラを作ってる人たちより賢いユーザは極少数

396:デフォルトの名無しさん
09/10/08 12:56:15
とも限らない

397:デフォルトの名無しさん
09/10/08 14:35:29
ゆとりはRDTSCの使い方も知らんのか

398:デフォルトの名無しさん
09/10/08 14:50:11
ちょっと面倒

399:デフォルトの名無しさん
09/10/08 15:58:42
逆数乗算で商を求めて元の値から引いたほうが速い
今のCore MAでは整数乗算は浮動小数除算機と兼用してて
非除数 - (除数×小数点以下切り捨てた商)

まあベンチ取ってみればわかるがコンパイラの吐くコードにも勝てんと思う

400:デフォルトの名無しさん
09/10/08 15:59:25
整数 ×乗算は ○乗算は 浮動小数除算機と兼用してて

401:デフォルトの名無しさん
09/10/08 17:45:39
static const int rcp6 = 1.0 / 6.0 * std::pow(2.0,16.0);
int x = 255 - ((255 * rcp6) >> 16) * 6;

確かにこれで十分な気がするし、>>387より速そうだ。


402: ◆0uxK91AxII
09/10/08 18:41:36
結果を使う40clk程度過去に除算を投げておくとか:b

403:387
09/10/08 21:02:29
申し訳ないけど俺のレベルが低すぎてまったく理解できん。

>>399
その「小数点以下切り捨てた商」はどうやって出したらいいの?

>>401

考え方だけでも教えて欲しい。

404:デフォルトの名無しさん
09/10/08 21:55:29
ここはアホしかいないからビット演算スレで適当に質問した方がいいよ

405:デフォルトの名無しさん
09/10/08 21:57:06
>>403
x / 6 = x * 1 / 6
これで、除算がなくなる。
ただ、1/6は小数点数になるから、整数演算じゃ表現出来ない。

>>399は、整数演算も少数演算もコストは同じだから少数でやれと。
>>401は、一時的に2^16倍してるだけ。

>その「小数点以下切り捨てた商」はどうやって出したらいいの? 
std::floor(x * 1.0 / 6.0)

406:デフォルトの名無しさん
09/10/08 22:29:32
手持ちのコンパイラで
int hoge(int a)
{
 return a % 6;
}
をコンパイルしてasm吐かせてみてよ
div使われてないと思うよ

407:デフォルトの名無しさん
09/10/08 23:14:01
VC9だとこうなった。
// const int x  = argc%6;
    mov ecx, DWORD PTR _argc$[esp-4]
    mov eax, 715827883              ; 2aaaaaabH
    imul    ecx
    mov eax, edx
    shr eax, 31                 ; 0000001fH
    add eax, edx
    lea eax, DWORD PTR [eax+eax*2]
    add eax, eax
    mov edx, ecx
    sub edx, eax

↓このブロックでargc/6を計算しているようだが、意味不明w
    mov eax, 715827883              ; 2aaaaaabH
    imul    ecx
    mov eax, edx
    shr eax, 31                 ; 0000001fH
    add eax, edx

つーか、eax * 3を計算するのに、LEAを使うのか。すげーなオイ。

408:387
09/10/08 23:24:00
VC6だと確かにDIV使ってたんですが…

今VS2008インストールしてみたら確かに>>407みたいな感じでした。
符号なしの場合で、一部整理すると(popとかも省略)
__asm{
mov ecx, DWORD PTR [m]
mov eax, 0aaaaaaabH
mul ecx
mov eax, ecx
shr edx, 2
lea ecx, [edx+edx*2]
add ecx, ecx
sub eax, ecx
ret 0
}
ぐはっ、まったく意味がわかりません!

409:デフォルトの名無しさん
09/10/08 23:45:46
VC5あたりで整数定数除算は掛け算になってたはず
剰余は確かめたことないな・・・

意味だけど、64bit固定小数点数で、小数点が32bit位置にあると考えると
(0x1_0000_0000 / 6) を掛けることは 6 で割ることになるでしょ

んでもって6掛けて元の数から引けば剰余になる
leaの計算は3倍してて、その後自身とのaddで2倍、都合6倍


>コンパイラを作ってる人たちより賢いユーザは極少数

ときどきasm吐かせてみたりしないと浦島太郎になるね。

410:デフォルトの名無しさん
09/10/08 23:50:55
mingw32 gcc 4.4.0

_hoge:
  pushl  %ebp
  movl   %esp, %ebp
  movl  8(%ebp), %eax
  movl  $6, %edx
  movl  %edx, %ecx
  cltd
  idivl %ecx
  movl  %edx, %eax
  leave
  ret

あれ?

411:デフォルトの名無しさん
09/10/08 23:53:54
マヌケなコンパイラだと大変ですね(^^)

412:,,・´∀`・,,)っ-○○○
09/10/09 00:08:33
64ビット整数の3の剰余を分岐も乗算使わずにハイパー高速に求めるアルゴリズム

n ^= n >> 32;
n ^= n >> 16;
n ^= n >> 8;
n ^= n >> 4;
n ^= n >> 2;
n &= 3;
n ^= ((n&1) << 1) | (n >> 1);

後半はLUT使ったほうが速いかもな

413:,,・´∀`・,,)っ-○○○
09/10/09 00:15:01
んで6の剰余ってこれでいいよな?

mod3(n >> 1) * 2 + (n & 1)

414:デフォルトの名無しさん
09/10/09 01:24:41
>>387
inline unsigned int mod6(unsigned int a){
 unsinged int b = (a >> 3) + (a >> 5); // /6
 unsinged int c = (b << 1) + (b << 2); // *6
 return a - c;
}

415:デフォルトの名無しさん
09/10/09 01:49:37
>>414
mod6 : 65536 % 6 = 4096
C    : 65536 % 6 = 4

mod6の/6が0.15625と、精度が悪いせいか?

416:,,・´∀`・,,)っ-○○○
09/10/09 02:02:30
その通り

417:,,・´∀`・,,)っ-○○○
09/10/09 02:09:39
でもまあショートカットとしては十分優秀だよ


SSEを用いた3の剰余のショートカット方法

movq xmm0, rcx
pxor xmm1, xmm1
psadbw xmm0, xmm1
movd ecx, xmm0

これで64ビットが11ビットくらいに縮まる

418:414
09/10/09 02:22:00
>>415
//もうすこし高精度版
inline unsigned int mod6(unsigned int a){
 unsigned int b = a >> 1;
 unsigned int c = b + (b >> 2);
 unsigned int d = c + (c >> 4);
 unsigned int e = d + (d >> 8);
 unsigned int a_div6 = e + (e >> 16) - b;
 unsigned int a_div6_mul6 = (a_div6 << 1)+(a_div6 << 2);
 return a - a_div6_mul6;
}

419:デフォルトの名無しさん
09/10/09 02:33:18
あんたらよくやるよ
templateで、任意除数版を作ってくれたら
俺様のライブラリに加えてやってもよいぞよ

420:デフォルトの名無しさん
09/10/09 02:34:59
>>419
コードが膨らんでキャッシュの効きが悪くなりそう

421:,,・´∀`・,,)っ-○○○
09/10/09 03:27:52
>>417
GCC4.4で-O3 -march=core2でコンパイルして
なぞの某パイプラインシミュレータ通したらトータルレイテンシ20サイクル, スループット10サイクルって出た

俺の>>412-413使った方法だとレイテンシ18と6
後半テーブル化すればもう少し減りそう
0, 1, 2, 3になったときに3だけを0に丸めるためだけにあほなビット演算やってるが
なんとかならんかな


422:-〇〇〇
09/10/09 10:10:58
>>412は嘘ですたorz
シフト+加算ならいけるんだが

423:デフォルトの名無しさん
09/10/09 11:19:23
団子かわいいよ団子


424:デフォルトの名無しさん
09/10/09 14:26:12
signedだが
妙に凝ったことやるよりこれが一番速いだろ
inline int mod6(int n) { return n - (_mm_cvttsd_si32(_mm_mul_sd(_mm_set_sd(n), _mm_set_sd(1.0/6))) * 6); }

425:デフォルトの名無しさん
09/10/09 19:44:48
mm...mmmとか読みにくくてかなわん
DirectXみたいなセンスが欲しい

426:デフォルトの名無しさん
09/10/10 01:05:31
……?

427:デフォルトの名無しさん
09/10/10 14:56:58
これがエスパー戦争の始まりである

428:デフォルトの名無しさん
09/10/10 14:59:45
結論

inline int mod6(unsigned int n) { return n%6; }

でおk

429:,,・´∀`・,,)っ-○○○
09/10/11 03:12:20
unsignedだとLSB保存して1ビット右シフトすればsignedで扱える
あとは>>424の方法でmod3を求めて2倍してLSB足せばOK

整数ベースでやるにはレイテンシ1の命令だけでなんとか工夫しないと
ちなみにpsadbwはレイテンシ3だからイマイチ
解説してなかったけどpsadbwが使える理由は

mod3(A * 2^24 + B * 2^16 + C * 2^8 + D)
= mod3(A + B + C + D)

だから。
A * 256 + B = (A * 255) + A + B

430:,,・´∀`・,,)っ-○○○
09/10/11 04:20:21
まあしかし、6の剰余程度だといずれの方法も大した意味は無いな
URLリンク(www.wikihouse.com)

431:デフォルトの名無しさん
09/10/11 05:07:16
CedarMillの88クロックってひどいな。

432:デフォルトの名無しさん
09/10/12 21:07:44
AMDがいきなりパなしてきたが・・・
URLリンク(developer.amd.com)

433:,,・´∀`・,,)っ-○○○
09/10/12 21:27:20
この手のはIntelコンパイラに標準で付いてきてるんだがな。まあ有償だが。
どのみちプロプライエタリならGPL/LGPLには組み込めん。


434:デフォルトの名無しさん
09/10/12 23:23:36
>>432
こういうのはコンパイラがチート使ってくれなきゃ
威力半減な気がするんだが、どうなのかね?

435:デフォルトの名無しさん
09/10/12 23:26:12
それをするのがコンパイラの仕事だろ

436:,,・´∀`・,,)っ-○○○
09/10/12 23:28:45
AMDは自社コンパイラを持ってないからな(あのお粗末なAMD Stream SDK以外)

437:デフォルトの名無しさん
09/10/14 22:23:37
スカラなんかどうでもいいよ。
SIMDをどうにかしろバカIntel。

438:,,・´∀`・,,)っ-○○○
09/10/14 23:00:54
SIMDでどうにかしろ

439:デフォルトの名無しさん
09/10/16 01:11:17
SIMDとか用語が嫌になる
しむど!
かっこわるー

440:,,・´∀`・,,)っ-○○○
09/10/16 01:12:15
ネイティブはシムディーって言ってるぞ


441:デフォルトの名無しさん
09/10/16 01:27:21
MMX
むむっくす!
かっこわるー
ネイティブでは?

442:デフォルトの名無しさん
09/10/16 11:21:57
えめめくす

443:デフォルトの名無しさん
09/10/16 20:57:46
かっこわるー

444:デフォルトの名無しさん
09/10/17 04:41:05
はいはい無限再帰無限再帰
66 e8 fc ff

445:デフォルトの名無しさん
09/10/17 23:55:00
かっこいいと思った用語

XMS
EMS
VMS

なんと!最後にMSが付く・・・・

446:デフォルトの名無しさん
09/10/17 23:58:17
あっちがっ・モビルスーツ!だからね!
まい・・・・じゃないんだからね!
誤解しないでよね!
↓死ねよガンオタしないでよね!!

447:,,・´∀`・,,)っ-○○○
09/10/18 00:00:55
>>445
腹筋運動マシン?

448:デフォルトの名無しさん
09/10/18 00:15:39
XMS
EMS
VMS
IMS
OMS
UMS
SMS


449:デフォルトの名無しさん
09/10/20 21:55:15
Large
Middle
Small

450: ◆0uxK91AxII
09/10/20 22:20:34
Long, Middle, Short corn.

451:デフォルトの名無しさん
09/10/21 01:58:29
CMS忘れるなよ

Chinko Manko, Sexだけどな

452:237
09/10/21 21:12:39
久しぶりにスレをのぞいてみたら、昔の自分のスレを発見。
そういや、こんなことしてたな。
団子さん、その節はお世話になりました。
あれからマシンもcore i7に代えたのでせっかくだからSSE4.2をためしてみた。
当たり前だけどやっぱり専用命令は速いね。
ところで_mm_popcnt_u32は使えたのに_mm_popcnt_u64はnot declared in this scopeって言われちゃった。
OSとかgccが32bitなのがいけないのかしら?


453:,,・´∀`・,,)っ-○◎○
09/10/21 21:18:27
64bit専用です

454:237
09/10/21 21:28:49
func =  reference :clock   =   14540000
func =        bit32 :clock   =    1710000
func =        bit64 :clock   =    4620000
func =           sse :clock   =     680000
func =  dango-sse :clock   =     430000
func =        sse42:clock   =     270000

文字数制限うぜぇ。削るのに手間取っちまった。しかも微妙にずれてるし。



455:デフォルトの名無しさん
09/10/21 21:32:01
>>453
どもです。
世間がwindows 7 で64bitへ本格的に移行してくれることを期待してまつ。


456:デフォルトの名無しさん
09/10/22 03:07:47
C/C++でメモリプール(int, doubleなど様々な型が共存)を作り、
メモリプール内部でメモリの詰め直しを行って最適化しようと試みています。

入門書+α(boostがわかるぐらい)なので、
キャッシュやメモリに関する特殊なことは全然わかりません。
何か気をつけなければならないことや忠告があれば教えてください。

457:デフォルトの名無しさん
09/10/22 03:23:42
>>456
メモリのことを知らずにどうやって最適化する気なのかね?

458:456
09/10/22 04:45:35
高速化が必要というわけではなくて、ガベージコレクションの宣伝文を見て
興味本位に詰め直しをやってみようと思いました。

空き領域を整えるだけでなく、アドレス配置を上手くソートすれば
キャッシュヒット率の向上ができると思いますが、それは難しいので
今回はプール内の空き領域を整えることだけに目的を留めて置きます。

プールはchar型の配列で確保し、memmove()でclassやプリミティブを
移動させる予定です。何か規則に反することなどがあれば教えてください。

459:デフォルトの名無しさん
09/10/22 05:00:47
そんな無駄な事をする意味がわからない

460:デフォルトの名無しさん
09/10/22 05:32:17
メモリコンパクションを実装するということは、
生ポインタから、ハンドル経由のアクセスに切り替えることになると思うけど

461:456
09/10/22 06:01:05
>>460
自作のスマートポインタを利用してアクセスを管理する予定になっています。
スマートポインタとコンパクションが同一のスレッドになければ危険ですが。

462:デフォルトの名無しさん
09/10/23 03:31:47
やってみりゃいいんじゃないの

463: ◆0uxK91AxII
09/10/23 04:39:52
下手の考え休むに似たり。

464:デフォルトの名無しさん
09/10/23 04:48:37
バウンダリに気を付けろよ

465:456
09/10/23 17:53:10
アライメント(構造体のサイズをバイトorワード境界に調整)はsizeof(...)使えば済むと思う。
でも開始アドレスもバイトorワード境界に調整する(これがバウンダリ?)のは知らなかった。



466:456
09/10/24 01:53:17
いや、アライメントを制御することをバウンダリと呼ぶという記事を見つけた。
だとすれば開始アドレスは特に気をつけることはないはず……。

467:デフォルトの名無しさん
09/10/24 02:02:00
他人に伝わらず、自分もよくわからない言葉を使うのは、とりあえずやめよう

468:デフォルトの名無しさん
09/10/24 03:17:08
何のためにアドレス調整するのか分かってんのか?


469:456
09/10/24 03:40:37
>>467
失礼しました。どうやら混乱してしまったようです。
とりあえず今日把握できた点について整理するために簡潔に書いてみます。

1.はじめに
32bitOSでは、4byte境界というものがある。
クラス・構造体であろうと、int,char,doubleなどのプリミティブ型であろうと、
インスタンスのサイズと開始アドレスは、4byte境界のルールに従うことになっている。。

2.サイズ
構造体やクラスは、4byte単位の大きさに整えられる場合がある。
以下のhogeクラスは5byteだが、4byte単位の大きさに整えられて8byteになる。
従って、sizeof(hoge)の返り値は8byteである。
ただしhelloクラスは4byte単位にされることはなく、
そのまま5byteなので注意が必要である。

class hoge
{
int i;
char c;
};

class hello
{
char c[5];
};

470:456
09/10/24 03:41:53
続き

3.開始アドレス
インスタンスが4byte境界を踏み越えないように、注意しなければならない。
具体的には、以下のように分類してインスタンスを配置すれば良い。
(※以下は正しいのか非常に不安)

・4byte以上の大きさを持つインスタンスの場合
開始アドレスが、4の倍数となる番号になるように配置する。

・3byteの大きさを持つインスタンスの場合
開始アドレスが、4byteで割り切れる番号になるように配置する。

・2byteの大きさを持つインスタンスの場合
開始アドレスが、2の倍数となる番号になるように配置する。

・1byteの大きさを持つインスタンスの場合
どこでもよい


参考URL
URLリンク(park21.wakwak.com)


次ページ
最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch