Aperyの指し手生成がMSVCだと遅い件

Aperyの指し手生成が(MSVCでコンパイルすると)遅いという話がなんとかちゃんねるに書いてあったわけであるが、その件は、やねうら王miniの指し手生成部を書くときに私も気づいたので(私のなかでは)すでに解決済みの問題であった。

AperyのUnrollerとは次のようなコードとなっている。

また、FORCE_INLINEは次のように定義されている。

ということで、残念ながらforce_inlineでカバー出来ることではなさそうである。(よくわからない。誰か追試して欲しい。)

そのため、やねうら王miniでは次のマクロを用いている。

この一件もあって、私のなかではlambdaが信用ならないというか、lambdaをきちんとコンパイルできないMSVC(Visual C++2015)を信用ならないというか、lambdaを使えという人を信用ならないというか、そのいずれもであるというか。

あまりlambdaの悪口を書くと、またC++なんちゃら委員会の人を怒らせてしまいかねないのでまあ、その件はこれくらいにしておく。

それはともかく、なんちゃらちゃんねるにはSDLチェックをオフにすればLinuxと同じぐらいのnpsが出るという書き込みもあった。しかし私が試した限りはSDLチェックをオフにしてもAperyのUnrollerでは指し手生成の速度は改善されなかった。また別の人の書き込みとして、「SDLチェックは/GLオプションをつけた時点で無視されている。」という書き込みもあったが、これは/GLではなく/GS-(セキュリティチェックの無効)のことだろう。

なんとかちゃんねるの情報から正しい情報を掬い上げるのはなかなか大変である。かつてひろゆきは、「うそはうそであると見抜ける人でないと(掲示板を使うのは)難しい」と言ったが、書き込む本人は嘘をついているという自覚がなくとも、本人の勘違いや検証不足・認識不足などにより意図せず間違った内容が書き込まれていることは多々ある。そういった間違った内容の書き込みから正しい情報を掬い上げることが出来ない人には(なんとかちゃんねるを使うのは)難しい。と言えるのかも知れない。

Aperyの指し手生成がMSVCだと遅い件」への10件のフィードバック

  1. ラムダは、関数を引数に取りたい時にすごい便利なんですよね。
    std::functionを引数にしておいてパペットだけ書いておけば汎用性のある関数が書けます。
    例えば2分法のロジックとf(x)=0を分離したりとか。
    しかし、屋根さんは独自にもうその辺は開発済みでしょうから、あまり恩恵はないかもですね。
    天才には時代があとから追いつくもんですよ。

  2. #pragma inline_depth(255)
    をプログラム先頭に書くと良いようです。なぜかと言えば、__forceinline によって Unroller は確かに unroll されるのですが、Unroller から呼び出されるラムダには __forceinline がついていないため (つける方法もなさそう) 関数呼び出しの深さが深すぎるという判断によりインライン展開してくれないのです。上記プラグマはそれを無効にします。このプラグマをグローバルにするのでなく局所的に適用しようといろいろ試してみたのですが私にはできませんでした

      • 再帰せずに unroll を実装するなら↓でしょうか…。これだと #pragma inline_depth なしでもきちんと展開されます (ラムダ本体が大きくなるとどうなるかわかりません)

        #include

        template
        __forceinline
        void Unroll_impl_(F&& f, std::integer_sequence)
        {
        auto wrapper = [i = int(), &f]() mutable { f(i); ++i; };
        [](auto…){}((wrapper(), seq)…); // 引数の評価順に依らず f(0),…,f(n-1)が呼ばれる
        }

        template
        __forceinline
        void Unroll(F&& f)
        {
        Unroll_impl_(std::forward(f), std::make_integer_sequence());
        }

        #include

        int main()
        {
        Unroll([](int i){
        std::printf(“ヽ( ・∀・)ノ● %d\n”, i);
        });
        }

          • すいません、角カッコが消えてしまいました。完全なのはこれです→ http://codepad.org/3wgtRtDf
            ここに貼るときは一応う○こを消したのですが codepad では消し忘れました

  3. AperyはSDLチェック外すと指し手生成速度は変わらないけど、NPSは1~2割程度上がりますよ。

    • やねうら王miniのほうはまだ探索部全く書けてないので、探索部まで書けたときに詳しく調べてみますね。それにしても指し手生成でSDLチェックをオンにしても生成速度が変わらないという事実のほうが私には不思議なんですけど…。

やねうらお へ返信する コメントをキャンセル

メールアドレスが公開されることはありません。 が付いている欄は必須項目です