株式会社はてなに入社しました
(ご報告遅くなって申し訳ありませんでした・・・)
なんだか知らない間にぜんっぜん関係ないtweetを拾われて勝手に憤られてた上に、全然まともに計算していないもの*1を出されてたので、ちゃんと動くようにして測りなおしました。
計算機は前回と同じものを使いますが、手元からVS2013がなくなってVS2015になってしまったので、Visual Studioのバージョンだけ違います(System.Numerics.Vectorsが必要ですが、4.1.0を使ってます)。
結果は以下の通り。
ということで、1秒ぐらい縮まりました。
FX-8350だとSIMD幅が128bitと判定されてSystem.Numerics.Vector<double>.Countが2になっていました(※先の記事の通りAVX2を使えば256bitできます)。
なので、2倍弱ぐらいは期待したのですが、結果は1.2倍で、ちょっと微妙な感じです。
関数呼び出しのコストがこんなに取られてるのか・・・よく分かりません。
私は最近まともなC#を書けてないので、まともなC#erさんに解明を期待します。
すいません、昨日眠い状態でコード書いてたので、最後にコミットせずにpushして安心して寝てしまってました・・・。多分昨日の時点ではSystem.Numerics.Vector<double>を使っても全然速くないどころか遅かったと思います。
正しいのはさっきコミットしました。これで、4.5秒ぐらい(x1.2ぐらい)です。
構造体もちゃんとサイズを切り分けたら、速くなりました。
なぜか2倍以上出ている・・・?まぁとりあえず速くなったので良しとします。
多分これが一番早いと思います(フラグ)。
@aokomoriuta @matarillo ちょっと動かしてみました。私の環境ではSIMD長=4に処理が飛んできたので、structでラップしないでナマのVector<double>の配列で試してみました。が、100msほど縮んだだけですね。
— てらだ (@u_1roh) 2015年9月21日
という話を聞いて、確かに手元のSurface Pro 3(OS:Win10、CPU:i3 4020Y)で試したところ、256bit SIMDになってくれました。
CPUが違うので単純比較できませんが・・・。
実行可能ファイルも置いておくので、もしお時間のある方は、OSとCPUの情報を添えて、実行時間とSIMD長を教えてくれると嬉しいです。
↓のコメントにある通りAkio Takahashiさんからpull requestもらってました。
全部は取り込みませんでしたが、一部を取り込んだところ、以下のようになりました。
以前の記事でC++のSIMD(AVX2)が1.3秒ぐらいだったので、同等ぐらいには速くなったようです。
ちょっと使い方に工夫が要るのかもしれませんが、C++と同じぐらいの性能がでるのであれば、C#には
という長所が3点あります。
積極的に使えるタイミングでは使っていきたいところですね。
*1:4倍近く加速されたとのことでしたが、System.Numerics.Vector<T>が何かをちゃんと理解できておらず、System.Numerics.Vector
@Tommy6がAMD Radeon R9 Fury Xを貸してくれたので、例のまたaokomoriuta.hateblo.jp
を使って測ってみました。
ソースコードも前と同じ場所にあります。普通にmakeすれば動くはずです。
結果、
Fury X (Fiji)
Normal: 44979[ms] Simd : 38869[ms] OpenMP: 8threads Normal: 12062[ms] Simd : 10243[ms] OpenCL: 730[ms]
290X (Hawaii)
Normal: 70199[ms] Simd : 61474[ms] OpenMP: 8threads Normal: 19010[ms] Simd : 16672[ms] OpenCL: 743[ms]
FuryXの方が10[ms]ですが速いですね!!
・・・誤差な気がする。
まぁ最適化もなにもしてないからなぁという気はしますが。
どっちかというと、Sandy-Bridge(2600K)よりIvy-Biridge(3770K)が1.5倍ぐらい速いのが気になるんですが・・・ほんとにこんなもんですかね?
をちょっと修正して
CPUで動かすようにしたので、手元にあった環境で動かしてみました。
$cd opencl_etc/cpu $make $./cpu = OpenCL on CPU = Normal: 7785[ms] OpenMP: 8threads Normal: 2124[ms] OpenCL: 1413[ms] == Platform : 0x7fde975d4670 == Name : AMD Accelerated Parallel Processing Vendor : Advanced Micro Devices, Inc. Version : OpenCL 2.0 AMD-APP (1598.5) == Device : 0x1642b10 == Name : Intel(R) Core(TM) i7-2600K CPU @ 3.40GHz Vendor : GenuineIntel (ID:4098) Version : OpenCL 1.2 AMD-APP (1598.5) Driver version : 1598.5 (sse2,avx) OpenCL C version : OpenCL C 1.2
OpenMPより倍速いだって・・・!?
なんか信じられないのでもうちょっと調べてみるけどあり得るのか・・・。
「gccのOpenMPが裏でpthreadを使っていて、OpenCLはTBBを使っていて、つまりpthreadよりTBBが速いのでは?」と言われたので、純AMD環境でVisualStudioでやってみました。
= OpenCL on CPU = Normal: 13274[ms] OpenMP: 8threads Normal: 2372[ms] OpenCL: 859[ms] == Platform : 000007FED1817B60 == Name : AMD Accelerated Parallel Processing Vendor : Advanced Micro Devices, Inc. Version : OpenCL 2.0 AMD-APP (1642.5) == Device : 0000000002EB1220 == Name : AMD FX(tm)-8350 Eight-Core Processor Vendor : AuthenticAMD (ID:4098) Version : OpenCL 1.2 AMD-APP (1642.5) Driver version : 1642.5 (sse2,avx,fma4) OpenCL C version : OpenCL C 1.2
1スレッド版が激遅なのはなんなのかって感じですがOpenCL版は更に速かったです。
うーん・・・なんなんでしょう。
この話。
男性は左が白で右が黒、女性は左が黒で右が白と認識するらしい pic.twitter.com/FydDcHZVH8
— 青子守歌 (@aokomoriuta) 2015, 5月 8
そもそもとしてそんな性差があると私は聞いたことがないです(自分で言っておきながら)。完全なる創作です(創作目的は後述)。
それはそれとして、いっぱいreplyやらmentionやらRTやら受けて、このまま「あー面白かった」で終わらせてももったいないので、せっかくなので統計とってみました。
結果は
でした。
もう少し詳しく言うと
ということでここでは白か黒かの認識に性差は関係ない(左が白で右が黒だという人のほうが多い)と結論づけます。
データは
google spreadsheetで見れます。
odsも置いておくので、データを追加したかったり色々したい人はここからダウンロードして下さい。
以下解説です。
*1:[要出典]な感じなので誰かよさ気な文献知ってたら教えてください
アライン忘れてましたごめんなさい、でも時間あんまり変わってないから許して・・・ https://t.co/JNtq2U2kMq
— 青子守歌 (@aokomoriuta) April 29, 2015
では本編どうぞ↓
若干話題に乗り遅れた感ありますが。
けど、SSEも知らねー、SIMDも知らねー、なんか俺が書いたアルゴリズム遅いけどとりあえずOpenCLとかで高速化しよっかなーとかね、甘ったれてんじゃねえよ。CPUをもっと使いきれよ。お前のアオいコードのせいでCPUが泣いてるよ。っていう話ですよ。
とか言われてたので、検証することにした(やっつけ)。