Windows上でJWASM(フリーのMASM6互換アセンブラ)と98エミュを使ってのプログラム作成に関するエトセトラ。また、PC-98プログラミング関係の書籍紹介とか自作ソフトの進捗とかも。

※ネタがないので雑記です。

何年かぶりに最新のVC++をダウンロードして、初めてインラインアセンブラを使ってみました。
コンソールプログラム上でクイックソートを書いて比較してみよう、という定番のネタをやってみようと。
結論から言うといろいろやってもstd::sortにぼろ負けで、16万個のunsigned int並び替えで以下のような結果になりました。
PCの処理の重さとか並びでの誤差がありますが、元の数列は同じものを使ってます。
ほかのソートに切り替えとかはやってないので、5割増しよりマシなら、ド素人が適当にやった割にはまともなんじゃないか、と勝手に思ってますが、ガチの人がやったらどんな感じなんでしょうかね。

流石に遅いと評判のqsortには勝てました。
宣言などと再帰部分以外のソート関数は下手なりにアセンブラで書けました。

以下、感想とかそういうのです。
基本的な使用感としては、基本的にはMASM6や、JWASMでMACROやPROCなしのコードを書いている感じでした。
MMX使おうとか、変態的な最適化をかけようとかとしなければ、PC98用とさほど変わりないです。

クイックソートの実装の仕方は色々とバージョンアップを重ねて試しましたが、やり方次第で少ないと10%、多いと数倍ほど違いが出て面白かったです。
結局簡単そうなやり方では、先頭ピボットをピック、後ろの小さいの→前の大きいのと交互に検索して交互に空きスペースに放り込む、最後にピボットを空きに代入、が一番まともな速度になりました。
再帰を使った方が関一個数で完結するものよりも多少速いことが多そうですが(印象。詳しい統計とらず)、さほど変わりはなさそうです。
再帰を使った方がはるかに楽ですが。
同じものをscnsdで検索してまとめたりとかも試しましたが、その処理分で遅くなったので、乱数を並べて遊ぶレベルでは意味がなかったです。
特殊な場合とかをしっかりやれば変わるんでしょうが、そこまでする気はないですし。
まあ、一週間ほどの遊びとしてはこんなものでしょう。
使用価値がないのでコードは載せません。

●インラインアセンブラの注意点とかよくわからなかったところとかそういうのについて。
なにも調べずにやったため、アセンブラコード内で引数のポインタの得方がわかりませんでした。
ポインタを宣言してそれを代入、で代用可能でしたが、やや面倒でした。
C++の方ではポインタ+1はサイズ分足される、というのはアセンブラ脳の人間には罠でした。
[変数]ができないのはJWASMとかと一緒ですが、エラーが出ないので忘れやすいです。
ebx,esi,edi以外もアドレス指定できたり、スケールファクタが使えるのは(PC98でも386以降で使えますが)便利だと思いました。
デバッガで各種レジスタ、変数を確認できるのもとっても便利でした。



PC98のソフトを作ってるといつの間にかC++のインラインアセンブラが使えるようになっていた、というある種当然のようなお話でした。
今時だと、インラインアセンブラから入ってる人の方がはるかに多い気がしてなりませんが……。



追記
挿入ソートに切り替えを実装しなおしたり、同一チェックやピボットを3つからとるのを導入したバージョンも作れました。
挿入ソートはwikiに載ってたコードではなく、やねうらお氏のブログにあったものを元にしたところ、速度が格段に速くなり実用的になりました。
同じことでも考え方が違うと全然結果が違って面白いのがアセンブラだと思います。

結局std::sortには勝てませんでしたが、386以降でのクイックソートや挿入ソートを習得したので、将来シミュレーション系統のゲームなどに応用できるかも、と思いました。
dword幅をROL RORで回してソートすれば、ある程度の項目別ソートもできるしありだな、みたいな。
根本的にはバランス調整ができないので協力者がいないと作れる気がしませんし、スペック考えたら挿入ソートで遅くなる数は処理しきれないのは明らかだったりしますが。

最終結果(windows10、core-i5 6400環境 変数初期化以外インラインアセンブラで記述 変数の数は自由 計測は前後で標準ライブラリを呼び出して行ったのでかなりてきとーです)
std::sort500万個、そのままとソート済みと÷200000
517631500 nano sec
79319800 nano sec
341990500 nano sec

ソート済み対応同一チェックあり500万個、そのままとソート済みと÷200000
577519500 nano sec(約1.1倍)
154799700 nano sec(約2倍)
404159400 nano sec(約1.2倍)

下のとり方をソート済み対応に変更版500万個、そのままとソート済みと÷200000
542523900 nano sec
144345300 nano sec
832237900 nano sec

挿入ソート入りソートテスト500万個、そのままと÷200000
548752100 nano sec
946397300 nano sec

Menu

管理人/副管理人のみ編集できます