Linux memo 2019/11/07

● ARMの割り算
浮動小数点は遅かったり演算器がのってなかったりするので注意しましょう...と思っていた時期が私にもありました。
ARM Cortex-Aシリーズには、整数の割り算を行う命令がある(SDIV UDIV)が、これは最近までoptionalで、Virtualizationありのコアから必須となっている。みんな大好きCortex-A9は、たいていの場合は未対応。詳細はArm Compiler armasm User Guideあたりへ。
このため、gccで-mcpu=cortex-a9とか指定すると、gccはlibgccの中の関数(__aeabi_idiv() __aeabi_idivmod() __aeabi_uidiv() __aeabi_uidivmod())へフォールダウンするコードを吐く。...実行が遅い某プログラムのプロファイルを取って上記の名前の関数が出てきて、で調べてみて初めて知った。マジかよこいつNeonも乗ってるのに...なので、浮動小数点のほうが整数割り算より早かったりするのかもしれない。測ってないからしらんけど。
KMC Staff Blog:ARM Cortex-A15の整数除算命令
http://blog.kmckk.com/archives/4170081.html
ちなみに、Cortex-A7は対応してそう。A9からA7に乗り換えてるSoCが多いのは、プロセスノードへの対応もそうだけど、こういうとこも響いてんのかな。

● std::list<>やstd::set<>は使い物にならない?
アルゴリズム的にはstd::listやstd::setをつい使いたくなってしまうが、万とかのオーダにならない限りそこまでの差は出ない。むしろちまちました操作によるオーバヘッドのほうがでかいことも多い。
[C++] STLの型の使い分け - Qiita
https://qiita.com/h_hiro_/items/a83a8fd2391d4a3f0e1c
コンテナ内の検索の速度について - 空想犬猫記
http://xoinu.hatenablog.com/entry/2014/08/14/140105
つまり、たいていのものはstd::vector<>やstd::map<>で事足りる。
また、万とかのオーダになる場合は、どこまで最適化されたコードになるかはコンパイラやライブラリに依存することになり、古いツールチェーンだったり組み込みだったりするとロクに期待できないので、結局必要最小限に独自実装してしまいかねない。
ちなみに、入れ替えやソートをたくさん行う場合、コンテナの中身を実体で保持するとアロケートやコピーのオーバヘッドが大きくなるけど、どうするのがベストプラクティスなんだろ。個人的には、malloc,free(new,delete)の管理手間が増えるのを覚悟の上で、ポインタを保持する実装に置き換えてしまいがち。生ポにするくらいならshared_ptr<>のほうがいいんだろうけど。もちろん理想はフルにstd::moveが効くという前提で何も考えずに実体で保持するやり方のままということなんだろうけど。

● コンパイラの気持ちを考えた最適化
- グローバル変数はできるだけ使わない、使う場合もできるだけstaticつけてスコープを狭める。
- ポインタはできるだけ使わない、レファレンスなどで逃げるようにする、どうしても使わざるを得ない場合でもローカル変数に閉じてかつポインタのポインタなどを避ける。
- ローカル変数はケチらない。コンパイラのほうがうまくケチってくれる。むしろローカル変数を多用したほうがうまくコンパイラがケチってくれる。
- アラインメントとコピーサイズに注意する。char単位でちまちま処理するとたいていは遅い。memcpyの実装のアセンブリのがんばり具合を確認し、できるだけそれらに乗っかることを考えよう。
- CPUの気持ちを考えた最適化まで突っ込みたいものの、ぼく人見知りなので、CPUの個性に応じた最適化とかムリ。
- 最後に、-O2つけ忘れがないかを確認しよう。-Ogついてるだけでもかなり違う。

このブログ記事について

このページは、らるるが2019年11月 7日 01:01に書いたブログ記事です。

ひとつ前のブログ記事は「Linux memo 2019/10/26」です。

次のブログ記事は「Linux memo 2019/11/09」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

月別 アーカイブ

ウェブページ

Powered by Movable Type 7.9.0