【C++】高速化手法【SSE】2 [転載禁止]©2ch.net
■ このスレッドは過去ログ倉庫に格納されています
C++やインラインアセンブラ、SSEなどによる高速化の手法
について語りましょう。
前スレ
【C++】高速化手法【SSE】
http://peace.2ch.net/test/read.cgi/tech/1130349336/ SIMDの一番簡単とも思えるこんなコードでも
最適化に関して語れることは山ほどある >>322
やっぱこいつ絶対アドレス君だw
妙味の部分に草生やすってことは大したコード書いてない証拠みたいなもんだよ
コンパイラより1%速くなっただけでもドヤ顔するタイプだろ 絶対アドレス?
一番アクセスが速いのはスタック
ほぼ確実にL1キャッシュにある
一等地 アドレス含め、
デカい即値は色々と遅くなる要素だぞ 300 みたいなことはこのスレの本来の住民なら誰でも知ってるから
いちいち講釈垂れるのはスレの無駄遣いだからやらないだけ
FPGA だって互換性気にしなければオリジナルの CPU の IP 書けば済む話で
少なくともこの板でやる話ではない >>329
>>300にいろんな要素が詰まってるわけだけど
どの程度わかるかな? >>315
>MMXは除外しても、SSE2、SSE3、SSSE3、SSE4、SSE4.1、AVX、AVX2、AVX512に加えて、
>64bitでは一気に種類が2倍と、次々と登場する新命令ごとに最速のルーチン用意していく手間と、
知らなくてもいいことかもしれないけど、これはアセンブラ作者泣かせでもあったりする。
命令数が多すぎるので手作業での入力は例えテーブル方式を採用していても無理が有り、
インストラクションセットの表を自動的にテーブルに変換するようなプログラムをしなくては
ならなくなってきている。 >>300は非常に良い教材だよ
これだけで語れることは山ほどある
「誰でも知ってる」なんて言う人は
ほとんど何も知らない初心者だけ
>>332
全てのCPUに対して最適化したコードを書く人なんていないだろ
せいぜい128bit, 256bit, 512bit の3バージョンくらい
32bit 512bit なんていらんだろうし
マーケティング上の理由で作らされてる人がいるのか?
それなら御愁傷様
本当に最適化するなら対応命令だけじゃダメ
IceLakeはAVX512が遅いし
AMDも昔はAVXがとても遅い >>333
アセンブラ=アセンブリ言語を処理してマシン語に変換するコンパイラ
の話。 前半からアセンブリ言語での記述の話だと思ってしまった
命令数めちゃくちゃ多いよね
多いだけじゃなくて複雑にもなってる
{k1} とか {z} とか
まあそれでも(高級言語の)コンパイラを作るよりははるかに楽だろうけど >>326
前にアセンブラスレでこんなこと書いてた変なのがいたんだよ
>実際には問題がある。なぜなら、そんなにアドレスが大きいと、さっきから話題の
>mov al, my_mojiretu[rbx]
>という命令が使えなくなるからだ。
とか、
>RIP相対32bitdispだとアクセスできない場合が出てくる
>シンボルがRIP相対2GBに制限されるなどはあくまでCコンパイラの制限であって
>アセンブラはその制限を受けない
ちょっと考えれば64bitなのに2GB制限するオプションとか使ってDLLも作れなくなるような
記法が推奨されてるはずないよな
それで複数の人から突っ込まれたら、誤りを認めて引っ込めばいいものを、
ファビョって連投しまくるから、皆呆れて無視したってことがあったんだよ
挙句にこんなことまで言い出したり
>自分は 64BIT 用C/C++コンパイラをインストールして無いので、試せません。
>>326だってこいつの言ってることはおかしいと思うだろ? >>336
その人は、64BIT命令にとても詳し過ぎてみんなが理解できなかったようだ。 >>338
Microsoftの人より頭いいんだw
でも連投してるときはあまり余裕無さそうだったよw >>339
MSの人より頭が言いなんて、当たり前じゃない。
日本人をなめてはいけない。 純粋に技術競争になったら、日本は絶対にアメリカに勝つ。
いつもそうだったし、IT分野でもそう。
問題はアメリカ人は自分が負けそうになると、圧力をかけて壊してくることだ。 >>341
そういう考え方情けないわ
お前がまず手本を示して見ろよ >>336
そこだけ抜き出しても何が言いたいのかわかりません
スレタイとは関係なく
ただ人をバカにするためだけの書き込みなら
感心しない >>342
そうそう
40〜50行程度の32bitSSEの自慢のコード片を晒せば大体の実力は判るんじゃないかな
でもね、自分が本気で最適化する時は、IACAの分析結果じゃいい加減すぎて役に立たないから
人力で計算してたんだよね
社外に秘密にしたいパイプラインの実装の詳細を気前よくツールに実装するはずないよね
だから、IACAを使って最適化してるのを自慢してる辺り、あまり期待はしてないけどね IACAの使い方間違ってないか?
自力で計算するための情報を手っ取り早く得る為の物だぞ >>342
IT関連は狡猾な人が多いので、アイデアだけ真似されるので完成するまでは
公開しない。 >>344
40〜50行程度になる題材があればコードを書くよ
今更32bit SSEってのも
時代についていってない感じでイマイチだけど
最適化はその時代のCPU向けでいいのかな? >>341
IT分野で日本が技術力で勝ってると思ってるの?
頭がお花畑で良いねえ >>349
多くは無いが個人レベルでは勝てる人はいる。 量子コンピューターに日本人の名前がクレジットされる可能性は高い。
一方、○○互換のソフトウェアはほぼ100%が中国発。
一見欧州製のように見えてもほぼほぼ中国。
人工知能に中国人の名前がクレジットされる可能性は相当高い。 おそらく世界最初の人工知能は春麗とかいう名前になる。 >>352
日本の平均レベルが低いからといって、このスレに来ている人全員のレベルが
低いことにはならないということだよ。 日本とアメリカの技術力の比較の話から
なんで個人の能力に話をすり替える? >>355
日本では、かつては半導体業界に優秀な人が集まっていた。
その当時、日本を引っ張っていたのは平均レベルの人達ではなかったんだよ。
自分の周りの平均以下のプログラマを見て、それが日本を代表するプログラマの
レベルだと思ってもらっては困る。 しかも
勝てる人もいる
って
アメリカのトップに勝つ人がいるって言うなら多少の意味はあるけど 様は、生まれつきのIQや理解力や記憶力の話だ。
努力とかじゃない。純粋のそういうものを比較すれば、日本のTOP層は
MSのTOP層と互角に戦える。 >>357
TOPに勝てる人は要るよ。数学オリンピックとか見ていたら分かる。 IQ、理解力、記憶力
技術力からずいぶんと話題が変わって来たね >>359
想像じゃなくて具体的に示してください
数学オリンピックって
俺も出たけどね
そんな高校生の遊びと技術力を同一視しないで >>361
あなたは数学ヲタクなだけでプログラミングが出来ないから
生意気なことを言ってるのか? 本当に地数学オリンピックに出られるなら、プログラミングなんてアホみたいに
簡単なはずだ。嘘なんじゃないか。 >>363
プログラミングは勝負の世界ではなく、お金の世界だ。
金儲けの手段。数学がそんなに出来りゃ学者にでもなればいい。
コンピュータ系の教授なら簡単になれるはずだ。 勘違いしてる人がいるようだが、本当に数学オリンピックに出るような人は、
いろいろなことが出来て、プログラミングなんて簡単に出来てしまう。
実例で行けば語学も堪能で13ヶ国語がぺらぺら立ったりする人までいる。
実際、数学オリンピックに出られるような人は、自分でもそれが分かる。
何もかも簡単に理解できるのだ。 単なる局所的な最適化、高速化
と
コーディング
と
ソフト開発
は全然違うから
>>365
じゃあ収入で勝負するか? >>368
そんなことない。数学は頭脳の頂点にあるので、本当に何でも出来る。 数学の天才が本気で高速化したコード
興味があるなら素直にそういえば良いのに >>370
そんなのには興味ない。
俺も天才だし。 >>374
掲示板書き込みは、頭を使わないので簡単に出来るので全然違う。
他の人が思ってるように検索して調べることもしてない。
記憶に頼って書いてるだけなので簡単。一人には高度に見えるかも
しれないが、頭は停止状態で書いている。掲示板書き込みは頭の休憩。
プログラミングの勝負などは脳のフル活動が必要になるので
絶対にしたくない。特に天才の脳はフル活動すると疲れる。凡人とは違う
かも知れない。 >>375
誤:記憶に頼って書いてるだけなので簡単。一人には高度に見えるかも
正:記憶に頼って書いてるだけなので簡単。一般人には高度に見えるかも
ちなみに誤字脱字が多いのも、頭を休めながらテキトーに書いているからだ。
長文だから必死に書いている事は無い。キーボードはスラスラ打てるから。
一般人には分からないだろう。 数オリに幻想を抱いてるようじゃ
能力も知れてる
でもびっくりするくらい数学を知らない人もいるよね
自信満々でアップした行列の掛け算のコード
実は行列の掛け算を知らなくて掛け算になってないとか >>377
数学オリンピックは、出るだけでも少なくとも東大や、東大の大学院に入るより
ずっと難しい。マイクロソフトに入社するよりも難しい。
ハーバードやMITよりもずっと難しい。
工学系の教授になるよりも難しい。 >>378
それを俺に言ってどうするの?
俺のファンか? >>380
本当にそんなに頭がいいなら、どっかの教授にでもなったらいいでしょう。
こんなところで人を馬鹿にしてはいけません。 まあなんでもいいや
話をスレタイに戻そうぜ
とりあえず天才の>>381
>>300のコードの問題点と修正コードをよろしくね >>382
俺は虚言ではない。
俺が嘘をついていると思ってるから、嘘で対抗しているの?
それは間違い。 >>383
SIMD命令には詳しく無いので、検索して調べないといけないのでやりません。
ここは頭を休める場所として使っているので、頭を使うことは出来ないのです。 実は、高IQ者が休憩時間に簡単なおしゃべりのつもりで言っていることが、
一般人には、高度すぎて勝負をしてきていると思ったりする可能性があります。
こういうことでギフテッドは一般の学校でトラブルになり易いのです。
本人は勝負のつもりではなく、とても簡単に言っているのです。一般人は、
勝負だと受け止めます。これが軋轢になるのです。 じゃあ何に詳しいんだ?
別に頭を使うようなコードでもないけどねえ
単なる知識の問題
考慮すべき内容は大きく分けて5個 マウンティング合戦で過疎スレを伸ばさないでくれよ。
質問攻めして相手の揚げ足取りって馬鹿左翼みたいだし。
ループ {
sum = _mm_add_ps(sum, data[i]);
}
について語れるなら結論だけ書いてOKだよ。 ・レイテンシとスループット
・メモリ帯域
・CPUと搭載命令
・演算の順番と精度
・処理の構成
SIMDの一番簡単とも思えるこのコードで
このくらい語れることはある ・レイテンシとスループット
ADDPSは多くのCPUで
レイテンシ 3〜4クロック
スループット 0.5クロック/命令
(メモリリードもL1にデータがあれば0.5)
このコードは、
前の演算結果を使うので
このままだと1回のループに3〜4クロックかかってしまう
スループットを生かすには8個並列にする
ループ {
sum0 = _mm_add_ps(sum0, data[0]);
sum1 = _mm_add_ps(sum1, data[1]);
sum2 = _mm_add_ps(sum2, data[2]);
sum3 = _mm_add_ps(sum3, data[3]);
sum4 = _mm_add_ps(sum4, data[4]);
sum5 = _mm_add_ps(sum5, data[5]);
sum6 = _mm_add_ps(sum6, data[6]);
sum7 = _mm_add_ps(sum7, data[7]);
data += 8;
}
32bitコードでもSIMDレジスタが8個あるので
コンパイラはsumをレジスタに割り当ててくれることが期待できる
(一応確認する) ・メモリ帯域 / 処理の構成
このコードの性能が生かせるのは、
データがL1にある場合
メインメモリは非常に遅いので
大きなデータにこのループを使うと
ほとんど待ち時間になってしまう
(HTTなら他方のスレッドが動き放題)
小さなデータで頻繁に呼ばれるのであれば意味があるが(例えば低レイテンシが要求されるオーディオ処理)
大きなデータの場合はほとんどがメモリアクセス時間になってしまう
L1やL2に入るようにこまめにサイズを区切りながら処理をするとか
他の処理も合わせてループにすれば
メインメモリの帯域による性能劣化を減らす事が出来る
なのでこのループ自体の存在をまずは疑問視しよう ・CPUと搭載命令
128bit命令は古い
パフォーマンスが重要であれば
より性能のある256bit命令、512bit命令を使う
その為に、搭載命令を判別すること
・アラインメントと端数処理
メモリはキャッシュ境界をまたがない場合に性能が出る
今回の場合はデータが1個なので
前側端数と後側端数をゆっくり処理して
それ以外を高速なコードで処理をする
・演算順と演算精度
演算の順番で精度が悪化することがあるので注意
今回のコードは順番に足していくが
これは精度が悪化する順番である
(2^24個を超える個数の1を加え続ける事を考えると分かりやすい) >>397
なるほどね。かなり勉強になりました。
こんだけ簡潔に日本語で説明されているものは、そう簡単には
ネット検索では見つけられないんじゃないかと思います。
SIMD命令には詳しく有りませんが、ちゃんとレイテンシのことまで
考えないと真価を発揮できないようですね。
知りませんけど、Intelコンパイラでもここまでは自動最適化で
やってくれないかもしれませんね。実際どうなのかお聞きしてみたいものですが。
実はコンパイラの最適化というものは、コンパイラ作者自身はやりたいと思っていても、
実際にコンピュータに自動的にやらせるのは結構大変なものなのです。
細かな注意点が沢山あるためです。最大の問題は、レジスタが無限に
あるわけではないことと、特定のレジスタにしか対応していないマシン語が
あることから来ます。もう一つは、さまざまな型やサイズの変数があるために、
色々なパターンに対応するのが難しいことにあります。
そういうこととに加えてレイテンシの自動配慮などを行おうとすると、最適化を
自動的に行うコードは非常に複雑で膨大な量になるのです。
また、今のCPUには、レジスタは16本くらいと結構沢山有るので、レジスタが不足した
場合の処理は、滅多にテストできません。そのため、その最適化処理はなかなか
テストできないのです。ですので、生半可なテストでは間違いが含まれていても
分からないままコンパイラを出荷してしまう事がありえます。敢えてレジスタが3本しか
使えないようにした状態でコンパイラをテストしたりする方法も一つの手です。
または、テストを余りしなくても明らかに正しいことが分かるようにコーディングする
ことです。しかし、それは余り簡単なことでは有りません。 >>400
最適化に関して。
例えば、最適化は、色々なパターンの最適化をどのような順序で施すかによって、
最終コードの質が変わってくることがあります。というのは、人間にとっては
割と大丈夫なのですが、コンパイラにとっては、非常に複雑でそれ以上最適化
できないようなコードに見える状態に陥ってしまうことがあるからです。
普通は、少しずつ良いコードになるよな修正を何度も何度も繰り返して、それ以上
良いコードになる方法が分からなくなった時点で最適化が終わります。
ところが、いったん、悪いコードにしてから、もう一度最適化をしてみると、
最後のコードは良いコードになる場合があります。このような最適化は人間には
余り難しくないのですが、コンパイラにとっては大変なのです。
なぜなら、悪いコードになってもいい事を許しだすと、オセロの先読みの min, max
方の様な試行錯誤型の人工知能的なものが必要になるのですが、そのような最適化は、
普段は余り効果を発揮しにくいのに、処理時間が膨大になるためです。
人間は、一度最適化したコードは、何年もそのまま使います。ところが、コンパイラは、
10分に一度くらいは、ビルドし直します。ですので、最適化にかけられる時間が違うのです。
CPUが人間より速くても、このような事情があるので、人間より良いコードを出すのは
案外難しいのです。 アルゴリズムの最適化なら組み込み関数でもできる
なのに、アセンブラを使う理由があるのかって話なのに、なんで組み込み関数のサンプルなんだ?
自慢のコード片ってのは、アセンブラで書いたのに決まってるでしょ
言い争いしてたどっちが>>316なんだ? 「究極の最適化はアセンブラしかない」
これに反対する人はいないよな?
SIMDの高速化でIntrinsicsに対しての話
アルゴリズムの最適化?
そんなものIntrinsicsを使う必要すら無い 実際の開発現場では
(アセンブラではなくて)Intrinsicsを使うことが多い
これも別に誰も反対していない >>405
なんかあんたの主張はずれてんだよな
本当に「究極」を求めるのなら、自分も>>298が書いてるように、何もCPUのソフトウェアに
限定せずFPGAでもなんでも使えばいいと思う
Googleだって、TensorFlow専用のプロセッサを開発して運用してる
組み込み関数の利点としては、32bit・64bit、SSE・AVXへの変更はコンパイラのオプションだけで可能ってこと
XMMでも多少は速くなるのと、AVX2やAVX512への移植もインラインアセンブラからよりははるかにしやすい
Microsoftが64bit版VCでインラインアセンブラを廃止したのは賢明だと思う
アセンブリの致命的な欠点は、アルゴリズム上の変数とレジスタが一対一で対応しないことで、
上のsum1みたいな名前付きの変数でないことと、常にどのレジスタがどの変数を保持しているか追跡しなきゃならない
それに、インラインアセンブラが使えないコンパイラだと、インライン関数やOpenMPも使いづらい
シングルスレッドで1%速くなるよりOpenMPで手軽にマルチスレッド化した方が、よりお手軽に速くなる
それでもアセンブリを使いたいっていうなら、オープンソースでないか、組み込み関数より
最低でも5%、できれば10%以上速くなる時にして欲しい
世の中にはインラインアセンブラで書かれたがために64bitで動かせずに放置されたオープンソースの
プロジェクトが結構あるんだよ(特にAVISynthなどの動画フィルタプラグインとか、オープンソースではないけど、
Aviutlも作者がインラインアセンブラ?を使いまくったせいで64bit化出来ずにいる) >>408
横からだけど、最後の方はわかるけどコンパイラオプションのは組み込み関係ないし
単一の浮動小数点演算をSSEのレジスタ使うだけっしょ
あとハードの制約を外すんならSSEだのAVXだの選択肢に入らんでしょ
一般のPCにみんなついてるGPUだって使えるんだから
CPUの拡張命令を使うのはそれなりにハードの制約があるからだ ここはCPUの高速化のスレだから
GPUやFPGAの話は他で >>409
64bitはコンパイラオプションではなかったけど、わざわざ各バージョン向けのコードを用意しなくても
開発環境でまとめてビルドできるでしょ
>>410
たかがアセンブリで書いたくらいで「究極」なんてドヤ顔すんなってこと
頭のいいGoogleの人達は専用プロセッサを開発する選択をした
そこまで自信があるのなら、40〜50行程度の32bitSSEのアセンブリで書かれた自慢のコード片を晒してみたら? >>413
「弘法筆を選ばず」って諺があるように、本当に才能のある人はわざわざ手段限定してドヤ顔したりしないだろ
せこいマウント合戦繰り広げてたの見てると、器の小ささを感じてしまうんだよな
そんなの恥ずかしいから止めとけよ
それより、エレガントなコード片晒した方がかっこいいぞ Intelは、何年も前からパラレル・ユニバースってキャッチフレーズで細粒度のマルチスレッディングを
推進していて、Threading Building Block(TBB)とかOpenMPなんかを使って並列化で速度を稼げと言ってる
現在では、IntelのIPPやMKLもフリー化されて、定番の処理は予め用意されてる
動画処理なんかでも、フィルタやフレーム別に複数のバッファを用意してマルチスレッド化してると
スループットを稼ぐようになってるので、最適化が甘くてもハイパースレッディングで実行ユニットは埋められる
GPUで計算する場合はライブラリ呼び出しだし、64bitでインラインアセンブラを使えるIntelのコンパイラは
700ドル以上するし、GCCのasmは癖が強すぎてMASMやNASMへの移植の障害になるほど
そういうことで、現在では「アセンブリで究極の最適化」なんて、時代に取り残された年寄りの妄言みたいな
状態になってるから、組み込み関数使って保守性をよくしておけばいい マルチスレッド化してスループットを稼ぐようになってるので >>417
NetBurstと違って、スパコンの主流が数千から数十万コア以上の超並列マシンになって
そろそろ20年近く経つのに、まだこんなこと言ってるのがいるんだな
よくまあ、これで最適化を語ってたものだ なんでPen4なんかを持ち出すのか引っかかってたけど、もしかしてNehalem以降のCPUで
ハイパースレッディングが復活してるのも知らなかったとか?
>>286や>>287で
>コンパイラの最適化なんぞ知れてる
>その辺を最適化したければガシガシアセンブラだが
とか書いてたのがおかしいと思ったんだよな
シングルスレッドでしか動かないCPUなんかで、
HaswellやSkylake、IceLakeみたいな実行部の強化をするはずないだろ
OpenMPやTBBでマルチスレッド化すればベクタ化は組み込み関数でも十分だし、
メモリアクセスがネックになってるのに、どうしてマルチスレッドによる並列化に言及しないのか不思議だったんだよな スレッド分けももちろん重要です
まあ安直にOpenMPでも良いんですが
これも究極はスクラッチ
スーパーコンピューターと違って
普通のPCだとせいぜいHTTとマルチコアなので
まあそれほど複雑ではないですが
>>300の例だと、
演算ポートもロードポートもガラガラなので
HTTは非常に有効です
データがL1にあれば性能はほぼ倍になります
一方>>394の場合は演算ポートもロードポートもフルに使ってるので、
HTTの効果はありません
汎用整数命令や整数ベクタを使うスレッドに分けてあげましょう
まとまった単純な処理でHTTの効果が大きい物は
ポートがスカスカな糞コードですね
メモリ帯域で大きく性能が変わるコードも糞コード
これは>>395の通り スレッドの分け方はこのスレの趣旨とは違いそうなのでこの辺で > NetBurstと違って、スパコンの主流が数千から数十万コア以上の超並列マシンになってそろそろ20年近く経つ
というかこの人は何を言ってるのだろう。
スパコンなんて40年以上前から並列処理の性能ということも知らんとかまだ子供か学生かな?
当時のPen4のことも全然知らないんじゃないだろうか。NetBurstとスパコン比べて何が言いたかったのだろう。 ■ このスレッドは過去ログ倉庫に格納されています