【C++】高速化手法【SSE】2 [転載禁止]©2ch.net
■ このスレッドは過去ログ倉庫に格納されています
C++やインラインアセンブラ、SSEなどによる高速化の手法
について語りましょう。
前スレ
【C++】高速化手法【SSE】
http://peace.2ch.net/test/read.cgi/tech/1130349336/ >>201
上位の高速化も該当するから是非話題振ってね。
JITなんかもOK! >>203
命令レベルの並列化にしろマルチプロセッサでの並列化にしろ
クリティカルパスじゃない部分を見つけて並列化してるという点では一緒で
並列化のアプローチの仕方が違ってるだけなのは理解してるんでしょ?
命令レベルの並列化であるOoOの方が直接的にクリティカルパスの影響を受けて
並列化が並列化が制限されるようになったからハイパースレッディングが投入されたのに
メイニーコアでクリティカルパスが問題になるって言い方は引っかかるんだよ 【 オンラインTCGエディター 】 >>1
デュエル・マスターズ的な非電源TCGの 《 オンライン化ツクール系ソフト 》 制作の企画。
例えば、ガチンコ・ジャッジを直ぐにでも導入できる機能を持っておりながら、
当面それを扱わず単純化させておいて、事後的に導入拡張する際に当該システムを
ブロック構造の組み合わせで後付け挿入できるように予めシステム化してあるソフト(エディター)。
既存の非電源TCGを劣らずに再現できるならば大概のニーズに応えられる筈。
バトスピ、ヴァンガ、ウィクロス、ポケカ、デジモン、ゼクス、モンコレ、ガンダム・ウォー、ライブオン、ディメンション・ゼロ、カードヒーロー、シャーマン・キングなど
のシステムを完全再現できるように設計するけど、他に此のTCGの此のシステムは再現希望とか有ったら書いて。
マジック:ザ・ギャザリングの全システムを完全に再現するのは無理だから、此れだけは必用だ!って部分のみリクエストして。
WEB通信での対戦は、個vs個、多数乱戦、チームvsチーム、個vsチームを可能な仕様とする方針。
設計思想は 《 RPGツクール 》 が良いかな? 他に、優れたエディター有ったら挙げてみて。
個人や企業などのベンダーが提示する開発費(見積もり)で折り合えば、発注する。
↓
エディター群から基本コンセプトを絞り込む(もちろんオリジナルで優れた新ネタが有れば導入する)。
↓
遊戯王OCGに関しては、タッグフォース、ADS、デュエルオンラインを発注先ベンダーに研究させる。
なるべく前述3つで可能な再現は全て実装させる方向を目指す。 まぁ努力する・・・
バトスピ、ヴァンガ、バディ、デュエマなど発売済みゲームソフトが存在してるケースはベンダーに研究させる。
↓
各社TCGを再現するテストプレイ ⇒ 更に改良や修正。
↓
機能制限した下位版を5万円以上で発売 + デュエリ−グ用に改造した上位版でサーバー稼動=営業開始。
↑
下位版の改造および商用利用には、別途で当社との契約が必要。
さ〜て、製作ベンダー見つけよっと!ww(クス
http://wc2014.2ch.net/test/read.cgi/entrance2/1449039272/-18 さすがに[?]をエイと発音するのは苦しいぞ
実はmainie coreという架空世界のCPUの話をしているという可能性もあるけどな
学の無い語るに値しない人間なんだろう >>207
そうそう、気になって仕方なかったんだよ。 煽りじゃなくてぐうの音もでないような真実を突きつけてこそじゃねえかな 母国語英語、第二母国語C++と日本語な俺からするとMulti-をマルチって言うのも違和感あるけどな やっぱりこの板の住民は英語でレスする方が楽な感じですか?
苦手過ぎる… 匿名通信(Tor、i2p等)ができるファイル共有ソフトBitComet(ビットコメット)みたいな、
BitTorrentがオープンソースで開発されています
言語は何でも大丈夫だそうなので、P2P書きたい!って人居ませんか?
Covenantの作者(Lyrise)がそういう人と話したいそうなので、よろしければツイートお願いします
https://twitter.com/Lyrise_al
ちなみにオイラはCovenantの完成が待ち遠しいプログラミングできないアスペルガーw
The Covenant Project
概要
Covenantは、純粋P2Pのファイル共有ソフトです
目的
インターネットにおける権力による抑圧を排除することが最終的な目標です。 そのためにCovenantでは、中央に依存しない、高効率で検索能力の高いファイル共有の機能をユーザーに提供します
特徴
Covenant = Bittorrent + Abstract Network + DHT + (Search = WoT + PoW)
接続は抽象化されているので、I2P, Tor, TCP, Proxy, その他を利用可能です
DHTにはKademlia + コネクションプールを使用します
UPnPによってポートを解放することができますが、Port0でも利用可能です(接続数は少なくなります)
検索リクエスト、アップロード、ダウンロードなどのすべての通信はDHT的に分散され、特定のサーバーに依存しません
g 1次キャッシュに収まるスレッドを沢山作りたいとき、SSEやらAVX
のレジスタをメモリ代わりに使うのとメモリ直でアクセスするのとどっちが
キャッシュ乱さずに動くかな。
3次キャッシュは使いたくないし、2次キャッシュもスレッド切り替えだけに
消費させたいし。 >>223
理論的にはレジスタを使うほうが乱さないだろうけど、
コンパイラやプロセッサがどうするかは動かしてみないと分からないだろうね。 レジスタに収まるならレジスタの方が良いに決まってる 1次キャッシュに収まるなら他のキャッシュなんて気にする必要は無いと思うんだが
普通のOSで普通のコードを動かすなら、スレッド切り替えによるオーバーヘッドなんて無視できるレベルだし
そんなことを心配するよりも、肝心なコードを気にしようよ
いろんなテクニックを知ってるからコードをアップしてくれれば、小さいループならお役にたてるかも知れない 最近ニコニコ動画に上がってる経済シミュ、生態シミュ動画の人の高速化手法がすごい std::copyってsimd化などの最適化って既にされてるのかな?
sse_copy()とか自作したとして
効果は期待出来る? sse_copyとやらはmemcpy、memmoveと何が違うの? 名前的に、SSEの128bitレジスタを使ってのコピーだろう
memcpyとmemmoveの違いはぐぐればすぐわかる じゃなくて、自作しようとしているSSEでコピーするであろう「sse_copy」と
標準で用意されている「memcpy、memmove」←両方合わせて、とで
何が違うの?という話
当たり前だがmemcpyはCPUがSIMDに対応していれば使うし
カリカリにチューニングしてあるわけだが
sse_copyなど要るの? memcpyはC言語の関数だったか
存在を忘れてた
こいつは最適化入ってるのね
これ使えば良さそうだ
そうする、どうもです 条件にもよるがmemcpyあたりはコンパイラ自身がインライン展開したりする std::copy使っておけばPODならmemcpyかmemmove使うんじゃないの
VS2017のやつはmemmove使ってるな 謎の速度低下で悩んでいたが、キャッシュレイアウトって重要だな。
AVX512で一部分だけ値更新したい時、16バイト読み込んでその位置に64バイト書き戻すようなケース。
そのまま16バイト読み込みで実装すると、読み込み時に16バイト分しかキャッシュがないので、書き込む時に64バイトに拡張というか再配置されて遅くなる。
最初から64バイトで読み出すと、サイズが変化しないので遅くならない。
ついつい、読み出し量が少ない方が速いに違いないと思い込んでしまう罠。 パーシャルライトって奴だな
キャッシュにも有効なのか
昔のPenProの頃の8/16bitレジスタへの書き込み後の32bit読み出しとか
HDDが2T超える頃の4Kセクタのパーティションでの位置ずれとか
信じられないほど遅くなる要因になるもんな え、memcpy()とかstd::copy()ってSIMD使うん??
vectorのコピー遅いから困ってて、カリカリとSIMDで書こうかと思ってたんやけど、手間省けるわ。 コピーが遅いから困っててと言うけれど
どうやって遅いと結論づけたのですか?
本来なら16ms完了するはずなのに29msもかかってしまっている!
とかわかるんですか? ああ、いえいえ、言い方が悪かったですが、
処理時間に占めるコピーの割合が増えてきたので、高速化したいなぁ、と思っただけです。 rep movsbが糞速い
https://srad.jp/~miyuri/journal/569822/
>>REP MOVSはマイクロコードで実装されていて、最初にコピーサイズを見て適するコピーアルゴリズムを決めるセットアップ処理を行なってから
>>実際のコピー処理を始めるようになっている。そのため小さいサイズのコピーではセットアップ時間のオーバーヘッドが無視できないが
>>コピーサイズ(適度に大きいサイズ)とアラインメントの要件とプロセッサの世代の条件を満たすとそこそこの性能が出る。
>
>>プロセッサの世代によって展開されるマイクロプログラムが変わり最適化の度合いも変わってくると。
>>第1世代Core i以降のプロセッサのREP MOVSのマイクロコードは比較的速い。
デコード済みの命令をキャッシュ出来るようになったから、マイクロコード展開命令でも最適化が行われるようになってるみたいだよ。 メモリのレイテンシ、スループットやキャッシュサイズに依存するんだから
ブロック転送命令の最適化は無駄な努力だとインテルは思ってんだろう。 Visual Studio 2017 で
memcpyを調べてみた
x86は rep movs
x64は vmovups 128bit 2パラ16アンロール
オプションでAVX2命令を使うようにしてもかわらず
vmovaps 256bit/512bitの方が速いから
頻繁に使うなら自作した方が良い >>238
キャッシュ可な領域はキャッシュライン単位でDRAMの読み書きが行われるはずだから
キャッシュは関係ないでしょ。 >>246
アライメントのほうだったかも。
境界跨いで更新する時、あらかじめ更新サイズで読み出しておけば、全領域使用可能状態になるが、読み出し半分だと残り分キャッシュ要求発生して遅くなると。 >>247
一定のストライドで読み込んでいれば自動プリフェッチで早めにキャッシュに取り込まれる可能性もあるけど、
DRAMの帯域を圧迫しないようにページ境界をまたいでは機能しないようになってるはずだったので、
AVX512のベクタ長だと、何サイクルか先のループで使うデータをプリフェッチで要求した方がいいかも。 >>248
ありがとう。すでに別件でPrefetchもやってみてるけど、AVX512だとかなり効果があった。 >>249
一時は自動プリフェッチの性能が向上してあまりprefetchの意味がない状態が続いていたけど、
AVX512ともなると1ページ分のデータをループ64回で消費しちゃうんだよな…
DRAMのCASレイテンシをCPUクロックで換算すると結構長いからね。 え?AVX512は手書きprefetchのほうが性能出る?
これまではハードウェアプリフェッチが超優秀で、手書きprefetchはむしろオーバーヘッドになって遅くなる感じだったんだけど。 prefetchはハードウェアにまかせて手書きでclflush入れるのが一番いい感じなんだけど。こんなケースは少数派なのかな。 xeonでavx命令使うと過熱防止のため1ms間、動作クロック下げるなんて聞いてないよ〜(>∀<) ☆ 日本の、改憲を行いましょう。現在、衆議員と参議院の
両院で、改憲議員が3分の2を超えております。
『憲法改正国民投票法』、でググってみてください。国会の発議は
すでに可能です。平和は勝ち取るものです。お願い致します。☆☆ 僕の知り合いの知り合いができたパソコン一台でお金持ちになれるやり方
役に立つかもしれません
グーグルで検索するといいかも『ネットで稼ぐ方法 モニアレフヌノ』
YF4RO 過熱してなくても1ms間、強制的にクロック下げるん? >>257、そうみたいなんですよ
https://pc.watch.impress.co.jp/img/pcw/docs/665/641/html/14.png.html
> AVX命令が実行されるときに、CPUはAVXベースで定義されている
> クロック周波数に一時的に下がって実行し、実行終了後元のベースクロックに戻る
> AVX命令の実行完了後1ms程度で通常(非AVX)動作モードに復帰 AVXが有効な処理なら微妙にクロックが落ちようがどうでもいい クロックが高いのが目的じゃなくて
処理が速いのが目的
その辺がよくわかってないアホがいるみたい Programmable Calculation Unit (嘘) XEON、AVX-512だとさらにクロック下がるぞ
コア数多いとさらにクロック低下するでw
Platinum 8180M 28C 2.5GHz -> 2.1GHz(AVX2) -> 1.7GHz(AVX-512)
Platinum 8153 16C 2.0GHz -> 1.6GHz(AVX2) -> 1.2GHz(AVX-512) そもそも4倍の量が同時に計算できるわけだから
クロックが半分になっても元は取れる クロックが実際は半分にならないから
メリットは高速化 これsum1()とsum2()でだいぶスピード違うんだが、みんな知ってた?
#include<vector>
#include<iostream>
using namespace std;
class Tree{
public:
long long i;
vector<Tree> v;
Tree(){i=0;}
long long sum1(){
long long x=i;
for(vector<Tree>::iterator p=v.begin();p!=v.end();++p)x+=p->sum1();
return x;}
long long sum2(){
long long x=i;
for(auto p:v)x+=p.sum2();
return x;}
};
void big_tree(Tree *t,int d){
t->i=d;
if(d<=0)return;
t->v.push_back(Tree());
t->v.push_back(Tree());
big_tree(&(t->v[0]),d-1);
big_tree(&(t->v[1]),d-1);}
int main(){
Tree t;
big_tree(&t,20);
cout<<t.sum1()<<endl;
cout<<t.sum2()<<endl;
} そりゃ、やってることが違うんだから
同じにしたけりゃ sum2 で for (auto& p: v) にしてみ うお、autoってこんな書き方も出来るのかよw
勉強になりました。 結果は同じだろ? 鬼のように発生するコピーのためにメモリ不足で死なない限りは。 C++は、書いた通りに実行されるだけ。
高速な処理が必要なら、そう実行されるように実装しないと。 まるでC++コンパイラは最適化しないとかデタラメな言い分けだな。 何のためにコピーしてるん? 使い方間違ってんじゃね? reserveせずのpush_backしまくるバカのことじゃね? push_backしまくってもそれほどパフォーマンスは悪化しないように出来てるはずだが
コピーしまくりっていうんだから関数で値渡ししてるとかじゃないか?
いずれにしろC++自体の問題ではない データの並び順やアルゴリズム、...
この辺がパフォーマンスに大きな影響を与える
コンパイラの最適化なんぞ知れてる
その辺を最適化したければガシガシアセンブラだが
その前にいくらでもやることがあるのが普通 メインメモリが相対的に遅くなってきてるので
データの並びは非常に重要
大きなデータはディスクアクセスのような感覚で扱わないとダメ 突っ込みどころもあるが1年前のレスに真面目に返答してるおまえを評価する。 x おまえ
o おまえら
って書こうとしたが
同じ人だった orz 組み込み関数でSIMD命令駆使すれば、しっかり高速化されてキモティー! >>292
アセンブラを使わなくても速度チューニングネタはたくさんあるが
当然最後の手段としてはアセンブラは有効
小さいループに処理が集中してるような処理は
特に効果的
下手くそがアセンブラに手を出すと逆に遅くなったりもするけど >>292
急にどうしたw
レジスタ割り当て面倒くさいから、Intrinsics使うの普通だぞ >>295
>>286が
>コンパイラの最適化なんぞ知れてる
>その辺を最適化したければガシガシアセンブラだが
とか書いてたから
この人10年くらい時間が止まってるよね
64bitと32bitじゃレジスタの数も違うし、SIMDの新命令に対応させるたびに
レジスタ割り付けが全く変わってしまうこともあるのにアセンブラって…
AVXなら3オペランドも使えるから、コンパイラに任せてもコードの質は低下しにくくなってるはず 費用対効果を考えればIntrinsicsでも良いけど
究極の最適化はアセンブラしか無い
IACAを使ったり実測したりしながらパズルする
処理が非常に単純で速度の求められる小規模DSPなんかでも
いまだにそういう開発をする >>297
IACA=Intel Architecture Code Analyzer
ですよね。 SIMDを覚えたての初心者はこんなコードを書きやすい
典型的な糞コード
ループ {
sum = _mm_add_ps(sum, data[i]);
}
>>299
そうです >>298
CPU, GPU, FPGA
それぞれ得意分野が違うから GPUユニットはCPUに乗っけたのだから後はFPGAも乗っけるだけ。
アルテラは既に買収済みだしな。 ■ このスレッドは過去ログ倉庫に格納されています