アカウント名:
パスワード:
汎用のデジカメRaw現像ソフト。デコード部分のコードにコンパクトでパズルチックなものが多い。
富豪的プログラミングの名のもとに直接的なコードしか書けない自分には,なかなか参考には出来ないもののこういう世界もあるんだなと考えさせられる。
ちなみに,外部ライブラリを除けば単一ファイルで完結するソフトで,最新版の行数は9,519行と異常に長いのも特徴的。
レジスタに0代入より、自レジスタとXORの方が1クロック速い
クロックは同じで、命令が短いっていう印象。
xorというとビット反転に使うけど、プログラミングを始めた頃、BASICでA=1-Aとして0と1を切り替えていたのを見たときちょっと感動した記憶があります
Z80あたりの8bit CPUだと、
XOR A ; A=A^A
は4クロック、
LD A,0 ; A=n
は7クロックで、実際にXOR Aの方が速い。その理由は、命令が1バイト短いから。パイプラインも無いしねえ。
マシン語が想像できれば、応用が利きますよね。インストラクションセットによって違いますが、一般的には1)「値」を使うとコードに値が埋め込まれるのでコードが長くなる。当然、フェッチにもサイクルが増える。2)算術命令でも論理命令でもオペコードが少ない方が速い3)フラグが変化する命令はサイクルが長い場合もあるので、できればフラグ変化なしの命令を選ぶぐらいは通用しそう。実際は、コンパイラがどんなコード吐いてるか調べるのは実効速度に効くループの一番底ぐらいですけど。
> 1)「値」を使うとコードに値が埋め込まれるのでコードが長くなる。当然、フェッチにもサイクルが増える。
ところがどっこい。RISC系のアーキテクチャだと、即値ロード命令はその即値がオペコードに埋め込まれたものになってたりしますので、「コードが長くなる」ことはありません。ただし、「レジスタは32bit」「オペコードも全命令32bit」「即値代入で指定できるのは16bit」といった感じなので、その範囲を超えた値の即値代入は、複数回のロードに分割する必要があったりしますが…以下MIPSの例ですが、MIPSには即値ロード命令はありません。そのかわり、「値がゼロ固定のレジスタ0」なんてのもあったり(読み込みとして即値ゼロの代わり。書き込み先に使えば結果は保存されずフラグチェックだけができる)するので、R0との即値演算という形でR1クリアは、「R1 = R0 + 即値0」と記述したりします。なんか回りくどい命令記述ですが、でもそれでも1ワードの1命令で実行1クロック、とかになったりしますからねえ。#そういう即値指定ができるから、INCもDECも独立した命令は存在せず、通常の即値加算命令が使えたりとか。
Z80でアセンブラでコードをゴリゴリ書いて「XOR A が常識だろ」なんて考えていた身からすると、ちょっとカルチャーショックなアーキテクチャですね。
オッさんホイホイだなあ…。or aでゼロ比較ってのもあったかな。inc hlをinc lにとか単純なとこから、cpi&jp peとか、80倍は16倍+64倍とか、記憶の断片が…。
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
人生unstable -- あるハッカー
dcraw.c (スコア:2)
汎用のデジカメRaw現像ソフト。
デコード部分のコードにコンパクトでパズルチックなものが多い。
富豪的プログラミングの名のもとに直接的なコードしか書けない自分には,
なかなか参考には出来ないもののこういう世界もあるんだなと考えさせられる。
ちなみに,外部ライブラリを除けば単一ファイルで完結するソフトで,最新版の行数は9,519行と異常に長いのも特徴的。
Re: (スコア:3, 興味深い)
今を去ること数十年前、アセンブラ(というよりマシン語)で
事故^h^h自己書き換えをする処理を見たときとか
レジスタに0代入より、自レジスタとXORの方が1クロック速いとか見たとき
ちょっと感動した記憶があります
Re: (スコア:3)
クロックは同じで、命令が短いっていう印象。
xorというとビット反転に使うけど、プログラミングを始めた頃、BASICでA=1-Aとして0と1を切り替えていたのを見たとき
ちょっと感動した記憶があります
Re:dcraw.c (スコア:1)
レジスタに0代入より、自レジスタとXORの方が1クロック速い
クロックは同じで、命令が短いっていう印象。
Z80あたりの8bit CPUだと、
は4クロック、
は7クロックで、実際にXOR Aの方が速い。
その理由は、命令が1バイト短いから。パイプラインも無いしねえ。
Re:dcraw.c (スコア:1)
マシン語が想像できれば、応用が利きますよね。インストラクションセットによって違いますが、一般的には
1)「値」を使うとコードに値が埋め込まれるのでコードが長くなる。当然、フェッチにもサイクルが増える。
2)算術命令でも論理命令でもオペコードが少ない方が速い
3)フラグが変化する命令はサイクルが長い場合もあるので、できればフラグ変化なしの命令を選ぶ
ぐらいは通用しそう。
実際は、コンパイラがどんなコード吐いてるか調べるのは実効速度に効くループの一番底ぐらいですけど。
Re:dcraw.c (スコア:1)
> 1)「値」を使うとコードに値が埋め込まれるのでコードが長くなる。当然、フェッチにもサイクルが増える。
ところがどっこい。RISC系のアーキテクチャだと、即値ロード命令はその即値がオペコードに埋め込まれたものになってたりしますので、「コードが長くなる」ことはありません。
ただし、「レジスタは32bit」「オペコードも全命令32bit」「即値代入で指定できるのは16bit」といった感じなので、その範囲を超えた値の即値代入は、複数回のロードに分割する必要があったりしますが…
以下MIPSの例ですが、
MIPSには即値ロード命令はありません。そのかわり、「値がゼロ固定のレジスタ0」なんてのもあったり(読み込みとして即値ゼロの代わり。書き込み先に使えば結果は保存されずフラグチェックだけができる)するので、R0との即値演算という形で
R1クリアは、「R1 = R0 + 即値0」と記述したりします。
なんか回りくどい命令記述ですが、でもそれでも1ワードの1命令で実行1クロック、とかになったりしますからねえ。
#そういう即値指定ができるから、INCもDECも独立した命令は存在せず、通常の即値加算命令が使えたりとか。
Z80でアセンブラでコードをゴリゴリ書いて「XOR A が常識だろ」なんて考えていた身からすると、ちょっとカルチャーショックなアーキテクチャですね。
Re: (スコア:0)
オッさんホイホイだなあ…。
or aでゼロ比較ってのもあったかな。
inc hlをinc lにとか単純なとこから、cpi&jp peとか、80倍は16倍+64倍とか、記憶の断片が…。