読者です 読者をやめる 読者になる 読者になる

ai65536's blog

将棋とかプログラムとか

ARMのSIMDが遅い件

 

将棋エンジンはBitboardといって盤面を128ビットで表す技術が使われています。

Intel CPUではこの部分をSIMDを使うことによって高速化していますが、ARMではSIMDを使うと速度がでません。

 

気になって夜も寝られない(嘘)のでインストラクションマニュアルで調べてみました。

 

命令の実行速度に関係するレイテンシとスループットは大まかに以下のとおり。

レイテンシ:命令の実行が完了するまでのクロック数

スループットインテル  同じ命令を再度受け入れるようになるまでのクロック数

                         ARM  同じ命令を1クロックで何個入れられるか

スループットインテルとARMでマニュアルの記載の仕方に違いがあります。

 

Intelのインストラクション

http://www.intel.com/content/dam/www/public/ijkk/jp/ja/documents/developer/248966-024JA.pdf

And命令抜粋

128bit SIMD 命令

f:id:ai65536:20161025102431p:plain

※ 06_2A=Sandy Bridge  06=Family Number 2A=Model Number

汎用命令

f:id:ai65536:20161025103125p:plain

 

ARM Cortex A72 インストラクション

http://infocenter.arm.com/help/topic/com.arm.doc.uan0016a/cortex_a72_software_optimization_guide_external.pdf

And命令抜粋

SIMD命令

f:id:ai65536:20161025103941p:plain

スループットインテル風にすると0.5

汎用命令

f:id:ai65536:20161025103623p:plain

 

 

まとめ

Intelは汎用命令とSIMD命令でレイテンシ、スループットに差がないので、単純に処理するビット数が多い方が速くなる。

・ARMは汎用命令に比べてSIMD命令のレイテンシが3倍遅い。スループットが2(0.5)なので128bitの処理に単純に3倍かかると思われる。(スループットが1でも1.5倍遅い)

 

ARMのSIMDを使ったビット演算は遅い

 

最後に

マニュアルの見方がおかしいという場合は連絡ください

Androidで技巧ベンチ

新しいスマホを買ったので技巧でベンチ

前回のベンチからソート関連をいじってノード数が同じになるようにしたものです。

スマホ Snapdragn650 1.8GHz 

Windows Core i5 2500 3.3GHz

f:id:ai65536:20160723222226p:plain

シングルスレッド性能は3倍程度違います。

Snapdragon650は A72 x2 A53x4の構成なので、

だいたいSnapdragon650 6スレッド ≒ Corei 5 2500 1スレッドくらいでしょうか。

 

まだインテルの5年前のデスクトップ用CPUに追いつく感じではないですが、随分速度上がってますね。

 

追記2017/1/13

atomタブレットを買ったので計測

CPUはAtom x5-Z8300 1.44GHz

時間43.293s NPS 73107

チェリトレ世代のATOMで64bit SSE42対応ですが、

Cortex A72を搭載したスマホに勝てないですね。

 

 

 

Sortの挙動の違い

gccとMSVCでsortの挙動が違っていたのでメモ

同じ値のものを降順にソートした場合

 MSVCでは登録した順番に並ぶ

 GCCではバラバラになる

Ideone.com - ppnbu8 - Online C++0x Compiler & Debugging Tool

 

MSVCの方が望ましい結果だけど・・・ 

 追記:維持したい場合はstable_sort()を使うらしい

 

ソース

  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. using namespace std;
  5.  
  6. struct Data {
  7. char key;
  8. int value;
  9.  
  10. Data(char key, int value)
  11. {
  12. this->key = key;
  13. this->value = value;
  14. }
  15. };
  16.  
  17. inline bool is_greater(const Data& lhs, const Data& rhs) {
  18. return lhs.value > rhs.value;
  19. }
  20.  
  21. void print(const vector<Data>& datas)
  22. {
  23. for (auto& data : datas)
  24. {
  25. printf("%c %d\n", data.key, data.value);
  26. }
  27. }
  28.  
  29. int main() {
  30. // your code goes here
  31.  
  32. vector<Data> datas;
  33.  
  34. for (char ch = 'A'; ch <= 'Z'; ch++)
  35. {
  36. datas.push_back(Data(ch, 1));
  37.  
  38. }
  39.  
  40. std::sort(datas.begin(), datas.end(), is_greater);
  41.  
  42. print(datas);
  43.  
  44. return 0;
  45. }

結果

MSVC

A 1
B 1
C 1
D 1
E 1
F 1
G 1
H 1
I 1
J 1
K 1
L 1
M 1
N 1
O 1
P 1
Q 1
R 1
S 1
T 1
U 1
V 1
W 1
X 1
Y 1
Z 1

 

 

GCC

N 1
Z 1
Y 1
X 1
W 1
V 1
U 1
T 1
S 1
R 1
Q 1
P 1
O 1
A 1
M 1
L 1
K 1
J 1
I 1
H 1
G 1
F 1
E 1
D 1
C 1
B 1

 

 

Androidで技巧を動かしてみた

Androidで技巧を動かしてみました。

ソースコードGitHubにおいています。

バグってるかもしれませんがご容赦を・・・。

https://github.com/ai5/Gikou/tree/android

 

ベンチ

技巧にyaneuraOuのベンチを移植したそのベンチ結果です。

ベンチはシングルスレッドで3つの局面を指定の深さまで探索するというものです。

今回は深さ15にしています。

f:id:ai65536:20160604232708p:plain

32bit SSE2比で約1/10の性能です。オフィシャルとほぼ同等と思われるMINGW版との比較では1/20以上の差があります。

表にはのせていませんが、スマホAtom N2701.6GHz搭載のWinXPネットブックとベンチ結果は同じくらいでした。

 

PCもスマホも最新ではありませんがスマホでレート3000がでるんでしょうか?

スマホに最適化したエンジンが出てこないとまだ届かないかな。

 

VS2015+Xamarin.Androidで共有ライブラリを使う

Makefileプロジェクトで共有ライブラリを作る

特殊なことはしてない

chmod.c

#include <sys/stat.h>

int Chmod(const char* path, int mode)
{
return chmod(path, mode);
}

 Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_LDLIBS :=
LOCAL_MODULE := chmod
LOCAL_SRC_FILES := chmod.c

include $(BUILD_SHARED_LIBRARY)

 Application.mk

# Build both ARMv5TE and ARMv7-A machine code.
APP_ABI := armeabi armeabi-v7a x86 x86_64 arm64-v8a

 

 Androidのプロジェクト~.csprojに作成した共有ライブラリを追加

・追加既存の項目、リンクとして追加で作成した共有ライブラリをAndroidのプロジェクトに追加する。

・追加したファイルのプロパティのビルドアクションをAndroidNativeLibraryにする。

f:id:ai65536:20160502120439p:plain

・プロジェクトファイルを直接編集してAbi(以下の赤字部分)を指定する

<AndroidNativeLibrary Include="../chmod/libs/x86/libchmod.so">
 <Link>libs\x86\libchmod.so</Link>
 <Abi>x86</Abi>
</AndroidNativeLibrary>
<AndroidNativeLibrary Include="../chmod/libs/armeabi/libchmod.so">
 <Link>libs\armeabi\libchmod.so</Link>
 <Abi>armeabi</Abi>
</AndroidNativeLibrary>
<AndroidNativeLibrary Include="..\chmod\libs\armeabi-v7a\libchmod.so">
 <Link>libs\ameabi-v7a\libchmod.so</Link>
 <Abi>armeabi-v7a</Abi>
</AndroidNativeLibrary>

・適当なクラスに宣言を書く

public class Hoge

{

  [DllImport("libchmod.so")]
  public static extern int Chmod(string path, int mode);

}

 

 これでHoge.Chmod("hogehoge", 484);とかで呼び出すとNative側の処理が呼び出される。

 

Visual Studio 2015でAndroid NDKを使った時のメモその1

既存のMakefileをそのまま使う場合

・プロジェクトの新規作成でメイクファイルプロジェクトを選択する。

 

f:id:ai65536:20160430184015p:plain

・作成したソリューションのディレクトリに以前作っていたAndroid.mk,Application.mkをjniディレクトリごとソリューションのディレクトリにコピーする。(この場合はI:\TestProj\Project1\jni"みたいな配置。

・必要なソースファイルもAndroid.mk等の指定から矛盾の内容にコピーする。

 

・ビルドをするとlibs/armeabi/ほげみたいな感じでファイルができる。

 

 

Apery 32bitをShogiGUIで使う

Apery 32bitをShogiGUIで使う場合のインストール方法です。

ShogiGUIをイントールする

 

ShogiGUI - コンピュータ将棋 からShogiGUIをダウンロードします。

f:id:ai65536:20150527155141j:plain

 

2015/5/27現在ではver 0.0.4.2が最新です。

はじめに - ShogiGUIにしたがってインストール作業をしてください。

 

Aperyをダウンロードする

http://hiraokatakuya.github.io/apery/からAperyの最新版をダウンロードします。

f:id:ai65536:20150527155815j:plain

 

f:id:ai65536:20150527160023j:plain

 

ダウンロードしたAperyを展開します。

ダウンロードしたapery_wcsc25.zipを展開します。

f:id:ai65536:20150527160620j:plain

 

 

展開したファイルを適当な場所にコピーします。

展開したファイルを適当な場所(今回はD:\engine\apery_wcsc25)へコピーします。

 

f:id:ai65536:20150527161656j:plain

srcフォルダとutilsフォルダは不要です。

このときbin以下のフォルダ名、ファイル名を変更しないでください。

Apery 32bitをダウンロード&展開

apery - コンピュータ将棋からAperyの32bit版をダウンロードします。

f:id:ai65536:20150527162443j:plain

apery_wcsc2_msvc.zipというファイルがダウンロードされるので、先ほどと同じ手順で展開します。

Apery 32bitをコピーする

展開したフォルダから32bit版のAperyを先ほどのフォルダd:\engine\Apery_wcsc25\binにコピーします。

 

f:id:ai65536:20150527163133j:plain

ShogiGUIにAperyを登録する。

・ShogiGUIを起動します。

ツールメニューからエンジン設定を選択します。

f:id:ai65536:20150527163534j:plain

・エンジン一覧が表示されるので、追加ボタンを押します。

f:id:ai65536:20150527163715j:plain

・ファイルを開くダイアログが表示されるので、先ほどのフォルダ(d:\engine\Apery_wcsc25\bin)に移動して、32bit版のexeを選択して、開くボタンを押します。

f:id:ai65536:20150527164112j:plain

・正常にAperyが起動すると、エンジン設定ダイアログが表示されるので、OKボタンを押してダイアログを閉じて登録は完了です。

f:id:ai65536:20150527164303j:plain

・登録が完了するとエンジン一覧に表示されます。

f:id:ai65536:20150527164548j:plain

これで対局や検討にAperyが使えるようになります。

・Aperyの起動が失敗する場合

f:id:ai65536:20150527164818j:plain

エンジンの起動に失敗しましたと表示される場合は、手順が間違っているか、メモリが足りないか、カルマが溜まっていますので、手順を見直すか、最新の64bitOS機を購入してください。

 

Aperyの登録はできたけど、上手く対局できない場合

メモリが足りないと対局開始時にエラーで落ちるようです。

人とAperyの対局では2GB、Apery同士の対局では4GB程度のメモリが搭載されているPCを使ってください。

落ちる場合の対応策としては・・・

・対応策その1 ハッシュメモリのサイズを見直す。

f:id:ai65536:20150527165343j:plain

 

・対応策その2 古いPCを粗大ごみに出して新しいPCを購入する。

タブレットの場合はメモリの多い機種を選んでください。Visitaマシンの場合は新しいPCの購入をおすすめします。

 

追記

WCSC25版で定跡を変更する

WCSC25版のデフォルト定跡は居飛車が多いそうです。

ですが、ちゃんと普通の定跡も入っている入っています。

f:id:ai65536:20150528193613j:plain

memo.txtによるとbookall.binが普通の定跡のようです。

 

定跡の変更方法

ツールメニューからエンジン設定を選択する。

・Aperyを選択して設定ボタンを押す。

f:id:ai65536:20150528193757j:plain

 

・エンジン設定ダイアログが表示されるので、Book_Fileのbook.binをbookall.binに変更して、OKボタンを押す。

f:id:ai65536:20150528194043j:plain

 ↓ 変更後

f:id:ai65536:20150528194202j:plain

以上で定跡ファイルが変更されます。

 

PCが重たい場合

PCが重たい場合はスレッド数を調整してください。

ツールメニューのエンジン設定を選択します。

・エンジン一覧からAperyを選択して、設定ボタンを押します。

・エンジン設定ダイアログからThreadsを変更します。

f:id:ai65536:20150528194912j:plain

スレッド数の設定ですが、ShogiGUIのツールバーにコア数という表示があって、これの左側の数値以下(この場合は2以下、2で最大パフォーマンスになります)にします。

f:id:ai65536:20150528194945j:plain

・OKボタンを押してエンジン設定ダイアログを閉じます。

以上で完了です。スレッド数を減らしても重いという場合は新しいPCを購入してください。