やねうら王、各CPU向けの実行ファイルが用意できてない件

2017/5/11 4:30追記。皆様のお陰で一応解決しました。ご協力いただいた皆様、ありがとうございました。

一言で言うとgccの挙動がよくわからん。誰か助けて欲しい。

以下の作業はMSYS2上のgccでやっている。

1%でも実行速度が速いほうが良いので、まず、最適化オプションとして、-fltoを指定したい。この最適化オプションは、コンパイラ(CFLAGS)とリンカー(LDFLAGS)との両方につけないといけないらしい。

問題点1)
ところが、CFLAGSに-flto、-Ofastの二つを指定すると生成された実行ファイルを実行した途端にセグフォになる。空っぽのプロジェクト(空のmain関数だけのもの)でも同様にセグフォ。-flto、-O2にしても同様。-fltoをつけるときは、-O2を指定してはいけないのか?-O2をつけなければセグフォにはならない。

問題点2)
仕方ないので、-O2をつけるのはやめて、CFLAGSとLDFLAGSの両方に-fltoをつけてコンパイル。やねうら王でこれをやるとやはりセグフォ。魔女のMakefileを見たところ、あちらはCFLAGSには-fltoがついておらず(LDFLAGSにはついている)、-fltoをつけてコンパイルするとセグフォ。

2017/5/11 0:00追記 → 平岡さん : Aperyでは「MinGW で PGO ビルドが失敗する問題への対処として -flto オプションを外す。」 などとしている(´・_・`)

とのこと。Linux上なら問題ないようなのでMinGW固有の問題かも…。

問題点3)
各CPU用の実行ファイルを用意する方法がわからない。魔女のMakefileでSSE4.1用のビルドは以下のようになっている。

CFLAGS += -march=native
(中略)
sse41: $(MAKE) CFLAGS=’$(CFLAGS) -DNDEBUG -DHAVE_SSE4 -msse4.1′ LDFLAGS=’$(LDFLAGS) -flto’ $(TARGET)
やねうら王でもだいたい同様に指定しているのだが、これだとコンパイルするマシンに左右されるはずで、こうやって生成された実行ファイルはSSE4.1までしかサポートしていないPCで実行できないようだ。

2017/5/11 0:00追記 → -march=nativeはつけると駄目らしい。具体的なCPU名を指定したときにコンパイルエラーになるのは、また別の問題らしい。gccでは_blsr_u64()を使わないことにした。
2017/5/11 1:30追記 → -march=nativeを外すと各CPU向けの実行ファイル、無事生成されているようでした。(32bit OS向け以外)

問題点4)
よくわからないが、では具体的なCPUも指定しようと以下のようにした。

ところが、今度はコンパイルが通らない。

bitop.h

#define FORCE_INLINE __attribute__((always_inline)) inline (中略) #define BLSR(x) _blsr_u64(x) このBLSRを使ってあるところがinline化できないというエラーのようなのだが、そもそもCPU名を指定しないときは何故コンパイルが通っていたのだ?

2017/5/11 1:30追記 → 具体的なCPU名を指定するとこうなるようです。またgcc環境では_blsr_u64(x)は使わないようにしました。これなら具体的なCPU名を指定してあっても大丈夫なようです。

問題点5)
x86(32bit)用のコンパイル方法がわからない。SSEなし(nosse)用の実行ファイルは、x86用のつもりなのだが、どうやってx86用にすればいいのかわからない。

2017/5/11 0:00追記 → 本記事のコメント欄でいただいたコメントによると32bit用のコンパイル環境が別に必要そうなのだが…。
2017/5/11 1:00追記 → -m32オプション、mingw64では無視されるというのを知りませんでした。mingw32でコンパイル環境構築しました。
2017/5/11 4:30追記 →  Makefileを修正して、無事32bit用の実行ファイルが生成できました。

問題点6)
alignasの指定があるとARM用のコンパイルでコンパイルエラーになるらしいのだが、これ必要のない時にはつけないほうが良いのか?

2017/5/11 0:00追記 → あってもいいらしい。

やねうら王、各CPU向けの実行ファイルが用意できてない件」への20件のフィードバック

  1. 特にgccは詳しくないんですが、問題点5だけぐぐったらわかったのでコメントしておきます。
    まず、MySYS MinGW-64だと-m32オプションはさくっと無視されるようで、どうしてもMinGW-64で32bitバイナリを作りたい場合はMinGW-64(32bit環境用)というよくわからないものがあるらしいのでそっちを使えばいいそうです。また、代替としてMinGW-64ではなくTDM-GCCというものがあるらしいので、そちらを使うと-m32オプションはしっかり効くそうです。

  2. 問題点3
    >CFLAGS += -march=native
    これが不要です。
    nativeつけてるとコンパイルした環境に最適化されます。

    問題点6
    androidでの話ですが、alignasはamr64-v8a,STLがc++_static,TOOLCHAINが4.9だと問題ないです。

    androidはARMのABIがarmeabi,armeabi-v7a,arm64-v8aと3種類あって、STLの種類やツールチェインのバージョンなんかも複数あるので、もしかするとダメなパターンがあるのかも。

    • > nativeつけてるとコンパイルした環境に最適化されます。

      やはりそうですよね…。それで、alignasのほうは、つけておいても大丈夫ということですかね。色々ありがとうございます。

  3. gccには、関係ありませんが、iccでやると、ちょっとは性能上がるのでしょうか。(金払う価値あり?)

    • その昔、体験版で試したらVC++とさほど変わりませんでしたけども。いまはどうだかわかりません…。体験版で誰か試してもらえればと…。

コメントを残す

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