SSブログ

Aperyのdebug無しビルドでbenchが通らなかった問題の修正方法 [コンピュータ将棋]

 もういいやと思ってたが、たまたま見たログ見てたらstatic変数の問題っぽいような挙動に見えたのでソースいじったら直った

 static変数が定義されたヘッダファイルを複数のファイル(例えばa.cppとb.cpp)で参照されるヘッダファイルに入れた場合、a/bそれぞれにstatic変数がコンパイルされて、static変数が複数生成されるという現象がある。例えば1MBの配列になるstatic変数が定義されていると、a/bの中に1MBの配列が出来てイメージが2MBになる。

 今回の大本はテンプレート定数を引数にした配列を先に宣言してあって、その後に定数を宣言しているのが(mingw-w64のg++には)問題っぽい

 bitmap.hppの中では以下の様な定数が定義されている。

const Bitboard InFrontOfRank1Black = allZeroBB();
const Bitboard InFrontOfRank2Black = rankMask();
const Bitboard InFrontOfRank3Black = InFrontOfRank2Black | rankMask();

 extern const Bitboard InFrontMask[ColorNum][RankNum];


 InFrontMaskにはbitboard.cppに本体がある

243 const Bitboard InFrontMask[ColorNum][RankNum] = {
244 >---{ InFrontOfRank1Black, InFrontOfRank2Black, InFrontOfRank3Black, InFrontOfRank4Black, InFrontOfRank5Black,     InFrontOfRank6Black, InFrontOfRank7Black, InFrontOfRank8Black, InFrontOfRank9Black },
245 >---{ InFrontOfRank1White, InFrontOfRank2White, InFrontOfRank3White, InFrontOfRank4White, InFrontOfRank5White,     InFrontOfRank6White, InFrontOfRank7White, InFrontOfRank8White, InFrontOfRank9White }
246 };


 InFrontMaskの中身がいつ決定するか、何に決定されるかということだが、bitboard.cppだと確かにヘッダのコンパイルされた定数が入ることが期待できるのだが、他のcppファイルの場合、ヘッダに定義されているconstを使うと判断されてしまっているのではないかというのが予想。

 なので、対策として、ヘッダで定義されているInFrontOfRank1Black などの実体をcppに移しただけで直った。

 こんな感じ
 https://github.com/woodyring/apery/commit/e70bfa30e96e4b640a718a466734ec9f04418a3a

 VSのCLang 3.7やUbuntuのg++では問題なかったので、使ってるmingw-w64のg++の問題だと思う。mingw-w64のg++は5.2.0/5.3.0両方で発生。インストールしたのが年末で、update-coreすると5.3.0になってるが、どっちでも同じ現象だった。

 ただ、最適化をしたときだけ出てくれると、この説も説得力があるのだが、-O0でも発生するのでいまいち腑に落ちない。

<追記>

 https://msys2.github.io/

 ここからx64版をダウンロード
 http://repo.msys2.org/distrib/x86_64/msys2-x86_64-20150916.exe

 update-core
 pacman --needed -Sy bash pacman pacman-mirrors msys2-runtime
 pacman -Su
 pacman -S gcc make

 で多分同様の現象がおきるはず

nice!(0)  コメント(0)  トラックバック(0) 
共通テーマ:パソコン・インターネット

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。