アカウント名:
パスワード:
汎用のデジカメRaw現像ソフト。デコード部分のコードにコンパクトでパズルチックなものが多い。
富豪的プログラミングの名のもとに直接的なコードしか書けない自分には,なかなか参考には出来ないもののこういう世界もあるんだなと考えさせられる。
ちなみに,外部ライブラリを除けば単一ファイルで完結するソフトで,最新版の行数は9,519行と異常に長いのも特徴的。
レジスタに0代入より、自レジスタとXORの方が1クロック速い
クロックは同じで、命令が短いっていう印象。
xorというとビット反転に使うけど、プログラミングを始めた頃、BASICでA=1-Aとして0と1を切り替えていたのを見たときちょっと感動した記憶があります
ええ、初めは命令長の短さから使われ出したと思います。ところが、今時のx86 CPUだとxorでの0クリアは特別扱いされるので実際に速くなるはずです、こういう例もあるということで。
ASCII.jp:インテルCPU進化論 細かく変わって性能向上Sandy Bridge (5/5)|ロードマップでわかる!当世プロセッサー事情 [ascii.jp]
じゃあhacker's delightをおすすめ訳本もあるようなきがする
これかな?http://www.amazon.co.jp/dp/4434046683 [amazon.co.jp]http://www.hackersdelight.org/ [hackersdelight.org]
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倍とか、記憶の断片が…。
>A=1-Aとして0と1を切り替えていたのを見たとき
す、すごい!!!早速「if flg=1 flg=0 else flg=1」な感じのとこを置き換えました!天才っているもんなんだな・・
この手のコード自体は悪くないけどさ、こういうのを多用すると見通しが良くなくなるからなあ。バカがコードに目を通すこともあるわけでさ。
それを言いだすと、何のコード書けなくなるよ。
1~10まで説明しても、駄目って言うから、詳細を聞いてみたら、始めに説明した事まったく聞いてなくて出来ていなかった事が多々あると、残念な人を考慮してたら何のできないと思えるよ。
あなたの日本語が残念な気がする。
元コメはBASICの話だから仕方ないけど、Cなら三項演算子使う方が見通し良くないですか?
C で 0 か 1 が入っている int 型の変数の 0 と 1 を入れ替えたいときに、スピード優先 (?) で A = 1 - A とか A ^= 1 とかなら意図は理解できる (本当に速いかどうかは知らない) けど、見通しを良くするのが目的なら A = !A 一択じゃないの? 三項演算子を使うべき場面じゃないと思う。
VzでTABサイズの4と8の切り替えをht=12-htってコードでやってたのを思い出した
折角ですので、整数を4や8の倍数に切り上げる方法も考えてみてください。
普通にx = (x + 3) & ~3;とか。
2のべき乗限定の手法だと理解出来ないバカ^H^H初心者に考慮しないと駄目?
> 早速「if flg=1 flg=0 else flg=1」な感じのとこを置き換えました!
flg=0 or 1ならば、「flg ~= 1」の方がいいんじゃない?
a=3-aもある
クロック数と言えば、8086で、乗算を使わずに別の命令に展開するのもあったな。
今だと、ほとんど意味がなくなっているテクニックなんだろうな。これ。
整数変数×整定数だと今でもいろいろやるよ。 x86_64 の gcc で -O2 を付けてコンパイルしたら、シフトやら加減算やら LEA [mztn.org] やらに展開される。
lea命令って便利だよね。
a = a * 5; が lea eax,[eax+eax*4] になったりする。
これを便利と呼ぶか、 5 倍はできるけど 6 倍はできないなんて不便と呼ぶかは人による気がする……。
LEAってなんの役に立つんだって思ってたけど、こういうことをするための命令だったんですね。納得。
> A=1-A
たとえば、y = f(x) という関数を考えて、1→00→1なら、x→yの組み合わせが2つなので、パラメータ2個の式でパラメータ2個を適切に決めてやれば表現できますね。
x→yの組み合わせがn個なら、パラメータn個の式(たとえばn-1次の多項式)で表現できますね。
難しい上に乗算が出てきそうだから、テーブルから引けばいいやって思ってしまう。(´・ω・`)
プロセッサの処理能力が低くメモリ容量の制約も厳しかった昭和の時代、必死になって高速化とコードサイズ削減をするために使っていたテクニック今のプロセッサである程度の規模のアプリケーションを作る場合、コード全体に占めるゼロクリアの処理の割合なんかたかが知れているから実質的な効果は見込めない本当にギリギリまでオプティマイズかけなければいけない羽目になった時にだけ使えば良い
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
アレゲは一日にしてならず -- アレゲ研究家
dcraw.c (スコア:2)
汎用のデジカメRaw現像ソフト。
デコード部分のコードにコンパクトでパズルチックなものが多い。
富豪的プログラミングの名のもとに直接的なコードしか書けない自分には,
なかなか参考には出来ないもののこういう世界もあるんだなと考えさせられる。
ちなみに,外部ライブラリを除けば単一ファイルで完結するソフトで,最新版の行数は9,519行と異常に長いのも特徴的。
Re:dcraw.c (スコア:3, 興味深い)
今を去ること数十年前、アセンブラ(というよりマシン語)で
事故^h^h自己書き換えをする処理を見たときとか
レジスタに0代入より、自レジスタとXORの方が1クロック速いとか見たとき
ちょっと感動した記憶があります
Re:dcraw.c (スコア:3)
クロックは同じで、命令が短いっていう印象。
xorというとビット反転に使うけど、プログラミングを始めた頃、BASICでA=1-Aとして0と1を切り替えていたのを見たとき
ちょっと感動した記憶があります
Re:dcraw.c (スコア:2)
ええ、初めは命令長の短さから使われ出したと思います。ところが、今時のx86 CPUだとxorでの0クリアは特別扱いされるので実際に速くなるはずです、こういう例もあるということで。
ASCII.jp:インテルCPU進化論 細かく変わって性能向上Sandy Bridge (5/5)|ロードマップでわかる!当世プロセッサー事情 [ascii.jp]
Re: (スコア:0)
じゃあhacker's delightをおすすめ
訳本もあるようなきがする
Re:dcraw.c (スコア:1)
これかな?
http://www.amazon.co.jp/dp/4434046683 [amazon.co.jp]
http://www.hackersdelight.org/ [hackersdelight.org]
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倍とか、記憶の断片が…。
Re: (スコア:0)
>A=1-Aとして0と1を切り替えていたのを見たとき
す、すごい!!!
早速「if flg=1 flg=0 else flg=1」な感じのとこを置き換えました!
天才っているもんなんだな・・
Re:dcraw.c (スコア:1)
この手のコード自体は悪くないけどさ、こういうのを多用すると見通しが良くなくなるからなあ。
バカがコードに目を通すこともあるわけでさ。
Re: (スコア:0)
それを言いだすと、何のコード書けなくなるよ。
1~10まで説明しても、駄目って言うから、詳細を聞いてみたら、始めに説明した事まったく聞いてなくて出来ていなかった事が多々あると、残念な人を考慮してたら何のできないと思えるよ。
Re: (スコア:0)
あなたの日本語が残念な気がする。
Re:dcraw.c (スコア:1)
Re: (スコア:0)
元コメはBASICの話だから仕方ないけど、Cなら三項演算子使う方が見通し良くないですか?
Re:dcraw.c (スコア:2)
C で 0 か 1 が入っている int 型の変数の 0 と 1 を入れ替えたいときに、スピード優先 (?) で A = 1 - A とか A ^= 1 とかなら意図は理解できる (本当に速いかどうかは知らない) けど、見通しを良くするのが目的なら A = !A 一択じゃないの? 三項演算子を使うべき場面じゃないと思う。
Re: (スコア:0)
VzでTABサイズの4と8の切り替えをht=12-htってコードでやってたのを思い出した
Re: (スコア:0)
折角ですので、整数を4や8の倍数に切り上げる方法も考えてみてください。
Re: (スコア:0)
普通に
x = (x + 3) & ~3;
とか。
2のべき乗限定の手法だと理解出来ないバカ^H^H初心者に考慮しないと駄目?
Re: (スコア:0)
> 早速「if flg=1 flg=0 else flg=1」な感じのとこを置き換えました!
flg=0 or 1ならば、「flg ~= 1」の方がいいんじゃない?
Re: (スコア:0)
a=3-aもある
Re: (スコア:0)
クロック数と言えば、8086で、乗算を使わずに別の命令に展開するのもあったな。
今だと、ほとんど意味がなくなっているテクニックなんだろうな。これ。
Re:dcraw.c (スコア:2)
整数変数×整定数だと今でもいろいろやるよ。 x86_64 の gcc で -O2 を付けてコンパイルしたら、シフトやら加減算やら LEA [mztn.org] やらに展開される。
Re:dcraw.c (スコア:1)
lea命令って便利だよね。
a = a * 5; が lea eax,[eax+eax*4] になったりする。
Re:dcraw.c (スコア:2)
これを便利と呼ぶか、 5 倍はできるけど 6 倍はできないなんて不便と呼ぶかは人による気がする……。
Re: (スコア:0)
LEAってなんの役に立つんだって思ってたけど、こういうことをするための命令だったんですね。納得。
Re: (スコア:0)
> A=1-A
たとえば、y = f(x) という関数を考えて、
1→0
0→1
なら、x→yの組み合わせが2つなので、パラメータ2個の式でパラメータ2個を適切に決めてやれば表現できますね。
x→yの組み合わせがn個なら、パラメータn個の式(たとえばn-1次の多項式)で表現できますね。
Re:dcraw.c (スコア:2)
難しい上に乗算が出てきそうだから、テーブルから引けばいいやって思ってしまう。
(´・ω・`)
Re: (スコア:0)
プロセッサの処理能力が低くメモリ容量の制約も厳しかった昭和の時代、必死になって高速化とコードサイズ削減をするために使っていたテクニック
今のプロセッサである程度の規模のアプリケーションを作る場合、コード全体に占めるゼロクリアの処理の割合なんかたかが知れているから実質的な効果は見込めない
本当にギリギリまでオプティマイズかけなければいけない羽目になった時にだけ使えば良い