トップページ⇒tech
1001コメント321KB

ビット演算

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2005/08/13(土) 16:27:55
厨房くさいトリッキーな高速化テクニックを集めてみませんか?
0153デフォルトの名無しさん2005/11/06(日) 11:56:24
>>152
話についていけないなら、無理してついてこなくていいんだよ。。(w
0154デフォルトの名無しさん2005/11/06(日) 13:21:55
とりあえず、高速に処理する方法から遠ざかっているよな
0155デフォルトの名無しさん2005/11/06(日) 13:23:37
>メモリテストなら、0を書き込むのはあまり意味が無い。

別にメモリのテストではなく、ある処理をしていて、磁気データやバーコードデータ
をある動きの中でゼロクリア&確認したいだけです。


0156デフォルトの名無しさん2005/11/06(日) 13:58:52
>>151
だからどういうエラーが考えられるのかは、
メモリとかのH/Wを勉強しないと分からないだろ?
0157デフォルトの名無しさん2005/11/06(日) 14:00:41
>>155
マルチスレッドなら、そういう確認は意味がなく、排他制御を考えた方が良いよ。
0158デフォルトの名無しさん2005/11/06(日) 14:04:32
>>151
配線によるエラーって、それこそチップ内部の配線で
特定のメモリセルブロックのみ断線とか混線とかしてる場合とか
コンデンサのチャージエラーとかグランドへの抜け(ショート)とかって話だよね?
0159デフォルトの名無しさん2005/11/06(日) 14:44:07
もはや録音テープと化してるなw
0160デフォルトの名無しさん2005/11/06(日) 16:04:27
>>151
お前、2進数だって説明で納得できるのか?
俺なら、0x00と0xffの場合とどう違うんだ?って思うぞ。
だからこそ、H/Wの勉強が必要なんじゃないのか?
0161デフォルトの名無しさん2005/11/06(日) 22:09:25
H/W の勉強って言ってる奴は、馬鹿じゃないのか?
いったいどの分野を指してるんだ?
0162デフォルトの名無しさん2005/11/08(火) 23:47:07
>>159
それは録音様がこのスレにも降臨なされたという意味ですか?
0163デフォルトの名無しさん2005/11/09(水) 09:16:09
うん
0164デフォルトの名無しさん2005/11/16(水) 08:57:48
>>161
遅レスだが、H/W診断プログラムを作成するのに
対象のH/Wを熟知してなきゃダメだろって思うんだが。
0165デフォルトの名無しさん2005/11/17(木) 06:00:16
知らない奴に使わせて無茶苦茶しても壊れない・・・ってのは製品ではいいがナマハードではだめか
0166デフォルトの名無しさん2005/11/18(金) 00:10:21
>>165
このポート、リード専用で、書くと物理的に壊れますから。とかなら経験あるなぁ。
0167デフォルトの名無しさん2005/11/20(日) 02:50:53
ああ、そういうの俺も経験ある
というか、outbにラッパー入っててあるポートへの出力に
アサート入ってた
0168デフォルトの名無しさん2005/11/29(火) 13:52:20
x++;
x=-!x;
ってどっちが速いの?><
0169デフォルトの名無しさん2005/11/29(火) 14:56:32
>>168
>x=-!x;
嫌がらせとしか思えない。
0170デフォルトの名無しさん2005/11/29(火) 16:23:31
>>168
!じゃなくて~だろ。
x = -~x; と x++; をgccで試したら同じアセンブラ吐いたので、答えは同じ。
0171デフォルトの名無しさん2005/11/29(火) 21:18:03
>>168
勿論x++;の方が速くタイプできるに決まっておろう。
0172デフォルトの名無しさん2005/11/29(火) 22:49:35
てか、x++; じゃなくて ++x; を使うように習慣付けとけ。
0173デフォルトの名無しさん2005/11/29(火) 23:41:18
>>172
なんで?
0174171≠1722005/11/29(火) 23:43:07
C++では前置と後置では意味が違ってくるから、C++を睨んで前置の習慣をつけるべき。
#だとは思うが、このスレでは別に指摘するほどのことじゃないと思う。
0175デフォルトの名無しさん2005/11/30(水) 00:02:59
Cで++xよりx++が好まれるのは、x += 2とした場合と左右の位置が変わらないから
・・・な気がする
0176デフォルトの名無しさん2005/11/30(水) 00:36:12
コンパイラやコンパイルオプションで変わる
0177デフォルトの名無しさん2005/11/30(水) 07:04:07
ハッカーの楽しみ買いました。
毎日オナニーしています。
0178デフォルトの名無しさん2005/11/30(水) 07:24:43
dst++ = src++;

こう書きたいからなぁ
0179デフォルトの名無しさん2005/11/30(水) 08:00:28
>>173
http://www5.atwiki.jp/vc310ice/pages/4.html#id_1308a768
0180デフォルトの名無しさん2005/11/30(水) 08:22:22
bcc32では
x++;の方が速かったです。

inc
と
not
neg
の違いでした。(-O2)
0181デフォルトの名無しさん2005/11/30(水) 15:36:53
ビット演算を用いることによりブランチフリーにする意義は?
0182デフォルトの名無しさん2005/11/30(水) 16:39:58
ストール避け
0183デフォルトの名無しさん2005/12/04(日) 16:20:12
ストールってなんですか?
わかりません><
0184デフォルトの名無しさん2005/12/04(日) 16:38:41
>>183
寒い時に使う奴だよ。
0185・∀・)っ-●○◎- ◆Pu/ODYSSEY 2005/12/04(日) 16:44:30
CPUは1つの命令を実行するのに何段階かの行程を経る必要があるのです。

モダンなCPUには丁度ベルトコンベアで流れ作業するような感じで、命令の実行までの処理を順番に
流していくための機構が備えられています。これをパイプラインという
これにより、見た目上、1つのパイプラインで1命令1クロックで命令が実行されることになります。

ただ、すぐ次の命令の流れが前の命令の実行結果に依存してる場合、

・投機実行を備えてないプロセッサの場合、分岐先が確定するまで
 何を流せばわかりません。したがって、それだけ待たされることになります。

・分岐予測&投機実行なんかが導入されてる場合(大抵のx86アーキはそう)でも、
 予測が外れた場合、投機してたステージを全部破棄して再度読み直すことになります。

10ステージのパイプラインなら10クロック+αは、分岐(or投機失敗)のたびに、
命令実行が止まることになります。これがストール。
0186デフォルトの名無しさん2005/12/04(日) 17:01:08
あーつまり エンスト は エンジンストール の略だ。
0187・∀・)っ-●○◎- ◆Pu/ODYSSEY 2005/12/04(日) 17:09:06
つまりストールマンは思考停止した人ってことくぁwせdrftgyふじこlp;「’」
0188デフォルトの名無しさん2005/12/04(日) 19:35:52
レジスタの値を0にするときなぜ以下のように書くのでしょうか?
xor eax, eax
0189デフォルトの名無しさん2005/12/04(日) 19:57:05
速いから
0190・∀・)っ-●○◎- ◆Pu/ODYSSEY 2005/12/04(日) 20:03:36
C言語で書くとこれと等価なんだけど
a ^= a;

XOR演算の定義は

入力1 入力2 出力
  0   0   0
  0   1   1
  1   0   1
  1   1   0

だから、同じ値でビット排他論理和を取ると、レジスタの値によらず必ずゼロになる。
これは大概の実装ではレジスタに0をロードするより速い。
01911882005/12/04(日) 20:05:42
>>190
詳しい説明ありがとうございました。
0192デフォルトの名無しさん2005/12/05(月) 02:57:33
>>185
わかりました><

ストールによるデメリットと、投機実行的中のメリットで期待値はトントンにはならないんですか?

ブランチフリーのが正しい姿勢なのですか?
0193デフォルトの名無しさん2005/12/05(月) 03:06:54
こんな質問をするなんてよく分かってない証拠ですね><

よくよく考えると今の質問はナンセンスでした。
ようするにブランチフリーにすると
パイプライン達を相対的に酷使し続けられるってことですね><
0194デフォルトの名無しさん2005/12/05(月) 03:09:29
それから、おだんごいただきます。><
っ-●○◎-
0195デフォルトの名無しさん2005/12/05(月) 04:30:18
最近はXORで初期化するよりイミディエイトで0入れた方が速いらしいが
0196デフォルトの名無しさん2005/12/05(月) 07:12:40
CPUによるよね。同じプログラムでもBCCとかはXORだけど
SHC(SHっていう日立製CPUのコンパイラ)だと0をセットしてるね。
0197デフォルトの名無しさん2005/12/05(月) 23:22:52
っ-●-----
余ったのでお返しします><
0198 ◆CHINPOGEDU 2005/12/05(月) 23:27:39
>>16
きめぇw
0199デフォルトの名無しさん2005/12/06(火) 00:28:12
>>198
そんなトリップ付けた奴に言われたかないだろうな。
0200・∀・)っ-●---- ◆Pu/ODYSSEY 2005/12/06(火) 00:48:37
SHって基本的に命令が全部16ビット固定長のアレか。
0201デフォルトの名無しさん2005/12/06(火) 21:04:57
XORとSUBはreg,regに限れば同じだよね?
0202デフォルトの名無しさん2005/12/06(火) 22:23:53
8080の古より0クリアにはxorと伝承されてきたのです。
#いや、subはフラグに影響を与えるから避けたと言うのが真相だと思うけど。
0203デフォルトの名無しさん2005/12/06(火) 22:50:44
xorもフラグに影響しますが。
じゃなくて、

フラグ(CY)に依存しないsub命令が8080/Z80には無かったから
XOR A でアキュームレータをゼロにするのが一般的だった。

本当に一番最初にXOR Aを見たときは、「こんなとこで何やってんだ」と思ったけどね。
XORの動作を確認して、初めて納得した。
だって、実際にXORを使う場面なんて、数値演算(暗号/画像等)以外では
ゼロクリア以外無いじゃん?
積極的に使ってあげないと。
0204デフォルトの名無しさん2005/12/06(火) 22:59:54
んー、と思って書いてみたものの、ちゃんとZ80にもSUBはあるなあ。記憶違いだ。
0205デフォルトの名無しさん2005/12/06(火) 23:49:06
離散数学って代数と関係あるの?
0206デフォルトの名無しさん2005/12/06(火) 23:59:24
>>203

CRC とか パリティとかで

あ、それ数値演算?

っつーか SUB も AND も数値演算ちゃうんかと
0207デフォルトの名無しさん2005/12/07(水) 09:14:51
論理演算
0208デフォルトの名無しさん2005/12/11(日) 01:01:51
>>203
MSX2のスプライトで脚光をあびたな
0209デフォルトの名無しさん2005/12/12(月) 14:40:43
比較って何命令かかりますか?
x>y
x==y
とか。
0210デフォルトの名無しさん2005/12/12(月) 15:29:26
マシンサイクルのことか?
0211デフォルトの名無しさん2005/12/12(月) 15:45:53
はい。
addとかより時間かかりますよねきっと
0212デフォルトの名無しさん2005/12/12(月) 15:51:37
おなじ
0213デフォルトの名無しさん2005/12/12(月) 15:53:04
えー、うちのマシンだと2時間くらいかかったぉ
0214デフォルトの名無しさん2005/12/12(月) 16:21:49
一概には、ステート数は言えない。
それは、例えばC言語での記述のことだと思うが、
マシン語の対応が、x,yが何であるのかによって
命令数も変わってくるし、例えそれが純粋な比較命令
cmp EAX, [mem]
一つであったとしても実行時間は
すんなり行けば、1サイクル(なおP4だと、1サイクルで最大3命令同時実行できる)
で済むかも知れないが、命令の並びによって余分に掛かることもあるし
最悪ペナルティが発生すると数十サイクル掛かることもある。
0215デフォルトの名無しさん2005/12/12(月) 17:10:11
ありがとうございました。
0216デフォルトの名無しさん2005/12/16(金) 15:17:48
addとorはどちらが速いですか?
0217デフォルトの名無しさん2005/12/16(金) 15:19:19
リファレンス嫁
0218デフォルトの名無しさん2005/12/16(金) 16:38:36
ビット演算とかしたことない素人です。
ある数nを2進数表示して
  n=u[0]+u[1]*2+u[2]*2^2+…
としたときのu[0〜N]を扱いたいんですが
どのようにしていいかわかりません。

もっと具体的に書くとある数aに対して
  a^u[0],(a^u[1])^2,(a^u[2])^4,…
を求めたいのです。

わかりやすく教えていただけるとありがたいです。
よろしくお願いします。

0219デフォルトの名無しさん2005/12/16(金) 17:05:29
for (int i = 0; i < N; ++i, n >>= 1) u[i] = n & 1;
0220デフォルトの名無しさん2005/12/16(金) 17:17:26
リファレンスはどこで閲覧できますか?
0221デフォルトの名無しさん2005/12/16(金) 17:30:02
チップベンダーのサイト
0222ハーピィ2005/12/17(土) 18:44:27
E・∇・ヨノシ <222ゲット♫
0223デフォルトの名無しさん2005/12/18(日) 00:53:38
ちょっと前の話題だが、X86でゼロクリアにXOR使うのは速度面ではなく、
即値使うより命令サイズが小さくなるからじゃなかったっけ?
0224デフォルトの名無しさん2005/12/18(日) 01:00:57
そう。
ただ、何故subじゃなくてxorなの?という話だった気がする。
0225・∀・)っ-●---- ◆Pu/ODYSSEY 2005/12/18(日) 01:27:57
論理回路の実験で半加算器・全加算器作ったことある奴ならわかると思うけど
ビット演算は原則的に同じビット同士で演算すればいいけど、算術演算は桁上げがあるから
回路の負担も大きいわけ。
実装によりSUBがXORより遅くなる可能性はあるが逆は原則としてないじゃん。

いずれにせよ、同じレジスタ同士のXOR演算はレジスタリネーミングのヒントを与える効果もあるし
(少なくともここ最近のIntel CPUの実装ではそう)積極的に使うべきである。
0226デフォルトの名無しさん2005/12/18(日) 03:11:54
あと、速度が一緒でもXORのほうが消費電力・発熱が僅かに少ないなんて利点もあるかも。
・・・仮にそうだとしてもホントにどーでもいいレベルの差だろうけどw
0227デフォルトの名無しさん2005/12/18(日) 03:30:20
>>225
同期回路ならまずそれはないな
0228・∀・)っ-●---- ◆Pu/ODYSSEY 2005/12/18(日) 03:50:18
ヒント:Pentium 4のレイテンシ・スループットを参照
0229デフォルトの名無しさん2005/12/18(日) 04:14:49
別スレでも暴れてるようだが、本物のバカだな。
「x86でsubではなくxorが使われるようになった理由」にPen4を持ち出すとは。

まあxorは単独bitで演算できるのは事実だが
8086や80386でレイテンシやスループットに差があったのか
調べてから書き込んだ方が、バカをさらさないで済むと思うぞ。
#俺は調べる気はないから、本当に差がある可能性もあるけどな。
0230・∀・)っ-●---- ◆Pu/ODYSSEY 2005/12/18(日) 04:20:02
>>229
攻撃的な人ですね。
事実を証明できない、調べる気もないならそんな縦読みできない長文を赤い顔して書きなさんな。
0231デフォルトの名無しさん2005/12/18(日) 04:29:02
自分以外の書き込みが全部同一人物に見えるのが、デムパの特徴。
0232・∀・)っ-●---- ◆Pu/ODYSSEY 2005/12/18(日) 04:33:42
8086は組み込み用途では現役です。まあ初期のものと実装変わってるかもしれないけど
http://www.intel.com/design/intarch/intel186/docs_186.htm
>>229は英語読めるようになってから出直してきてください
0233デフォルトの名無しさん2005/12/18(日) 04:34:47
証明

x86が世に出て、コンパイラがゼロクリアに(x86の)xorを使うようになった時代に
Pentium4は有りませんでした。

証明終
0234・∀・)っ-●---- ◆Pu/ODYSSEY 2005/12/18(日) 05:13:32
ADD/SUBのほうがAND/OR/XORより速くなってたらXORじゃなくてSUB使うこと推奨してないし
ノイマン型コンピュータが発明されてから、論理回路の理論は殆ど何も変わってないのですよ。

で、マニュアルによると

ADD/SUB/ADC/SBB
reg/memory with register to either 3/10
immediate from register/memory 4/16
immediate from accumulator 3/4

AND/OR/XOR
reg/memory and register to either 3/10
immediate to register/memory 4/10
immediate to accumulator 3/4
だそうだ。

ftp://download.intel.com/design/intarch/manuals/27095003.pdf

どうみてもXORのが優勢です。本当にありがとうございました。


Pentium4を例として挙げたのは、16ビットのALUを2個束ねたものを動作クロックずつタイミングずらして
実行するものだから。スタガードALUっていうらしいけど。
暇だったらZ80のマニュアルも調べてみて。こいつも「8ビットCPU」だが内部は4bitニコイチ実装だったはず。
0235・∀・)っ------- ◆Pu/ODYSSEY 2005/12/18(日) 05:14:55
×XORじゃなくてSUB使うこと推奨してないし
●XORじゃなくてSUB使うこと推奨してるはずだし
0236デフォルトの名無しさん2005/12/18(日) 05:35:28
なんかわからないけど
必死だね
0237デフォルトの名無しさん2005/12/18(日) 09:10:29
・∀・)っ------- ◆Pu/ODYSSEY

↑コイツ同期回路の意味分かってねーな
0238デフォルトの名無しさん2005/12/18(日) 12:08:45
大丈夫、暴れるコテに何言っても無駄だから。
0239デフォルトの名無しさん2005/12/18(日) 13:48:34
よくわからんが、レジスタの中身でなく、メモリをゼロクリアする場合はどうなの?
直接ゼロ書き込むほうが速そうな気もするが・・・

XORだとメモリの内容を一度レジスタに入れて、さらにそれを他のレジスタにコピー
し、XORした結果(当然ゼロ)をメモリにいれることになるよね?

お馬鹿ですまん・・・
0240・∀・)っ->229>237>238- ◆Pu/ODYSSEY 2005/12/18(日) 14:34:07
だんごさん無くなったので私怨満々な変な人刺しておきますね。
とりあえず、XORよりSUBでゼロクリアしたほうが速い処理系ってのは存在し得ないでしょ。

他の演算を見ても、仮に半分のビット数のALUを2回使って出力を得るような構成だったとしても、
同じ桁のみの演算で完結するならビット論理演算は繰上げ/繰下げを無視して実行できるから、
XORがSUBと同等かそれより少ないクロックで実行できることはどんな処理系

消費電流の観点から言ってもSUBを敢えて使う理由はない。
全加算器の実装だけど、入力がx, yとci(carry-in), 出力がsとco(carry-out)とすると

s = XOR(XOR(x, y), ci)
co = OR( OR( AND(x, y), AND(x, c0) ), AND(y, c0) )

まぁ基本的な素子もNANDもしくはNORの複数の組み合わせで扱われることが多いんだけど
全加算器でXOR2個分は少なくとも使うわけだから少なくとも必要なゲート数は圧倒的に加算のほうが多い。

引き算は2の補数に変換して1加えたものを足すから、1を最下位ビットの全加算器のcarry-inとして
扱っても、ビット反転+足し算だから、これより更にNOTゲート1個分ずつ増える。


>>239両方の入力に同じレジスタから信号通すように回路を組めばいいでしょ。
レジスタの内容のコピーってなにげに時間かかるよ。
0241・∀・)っ->229>237>238- ◆Pu/ODYSSEY 2005/12/18(日) 14:36:44
×2の補数に変換して
×1の補数に変換して

ここは理屈としてはこういうことなんだけど
-x == ~x + 1
0242・∀・)っ->229>237>238- ◆Pu/ODYSSEY 2005/12/18(日) 14:48:26
クロックが上がれば上がるほど信号遅延の問題はシビアになってくるよ。
俺に噛み付いてる香具師は電子の移動速度が無限に延ばせるとでも思ってるわけじゃないでしょうけど。

移動速度の限界があるからこそ、Pen4の倍速ALUは32ビットではなく16ビット×2という構成をとらざるを得なかった。
0243デフォルトの名無しさん2005/12/18(日) 16:32:49
なんつーか、そもそも根本から話の観点が間違っているのに自分の風呂敷広げる以外に何も見えなくなっている様が哀れ蚊のようだ。
0244デフォルトの名無しさん2005/12/18(日) 17:43:38
xor使うのは、代入より早くてスマートだって感じで、あとフラグの動作とかで使ってただけだなあ。
subでもよい場面も数多くあっただろうけど、わざわざその場合だけsubにするのは逆に変だし
バグりそうな気がしてね。(あくまで気がするだけでこんなことで本気でバグるとは思ってない)
あと読む人だってxorの方が慣れてるだろうし。

今じゃ、別な意味でxor使うね。(暴れている人の意見に同意)
昔は、xorなんてループの外に出すものと決まってたけど
逆にループの中に入れて毎回実行させるほうが圧倒的に早い場面もあるし。
0245デフォルトの名無しさん2005/12/18(日) 18:27:53
ここってプログラム板ですよね。
一応念のために聞きますが・・・
0246デフォルトの名無しさん2005/12/18(日) 18:39:33
メモリをゼロクリアするとき、アセンブラがこんなん吐きました

ゼロを代入

MOV    #0, R1
MOV.L   R1,@R4

XOR

MOV.L  @R4, R6
MOV.L  @R4, R2
XOR     R2, R6
MOV.L   R6,@R4

コンパイラはSHC(SHっていわれるCPU用のコンパイラ)です(ver9.0)
0247デフォルトの名無しさん2005/12/18(日) 18:40:52
0248 ◆Pu/ODYSSEY 2005/12/18(日) 20:38:53
私怨で食って掛かって、論破されるとスレ違いだ云々わめく詭弁者って
どこにでもいるんだよね。

大学時代にとってた教養科目で、算術演算が整数加算しかない仮想
プロセッサで机上プログラミングをする内容の回があったんだが
引き算に補数をとって加算するのを地でやってた。

ネットで調べてみるに、どうやら昔の安いプロセッサって大抵
こういう実装だったらしい。
XOR使うって慣習はこの頃に確立されてたんじゃねーのかね。

算術演算がXOR演算を部分的に利用して実装している以上、XORそのものより
クロック数が多くなることはあっても少なくなることは絶対にないし、
むしろ高クロック化と多ビット化で桁上げの信号遅延が深刻になり、
再び乖離していくんじゃないかと思う。

だからたとえ今XORとSUBが同じクロックで実行できるとしても
ゼロクリアのXORをSUBに強いて置き換える真似はしない。
0249デフォルトの名無しさん2005/12/18(日) 20:59:24
論理回路
AND, OR, NOT, NORとかで
XORとかSUBを実現させようと図を作成してみたら面白いよね。
一気にSUB使いたくなくなる。
0250デフォルトの名無しさん2005/12/18(日) 21:18:34
>>248
こんなところで真面目に言っても意味ない
図に乗るな!って言って止めればよいだけ
0251デフォルトの名無しさん2005/12/18(日) 21:30:42
正論だったとしても一言二言余計な事を書くから叩かれる訳で。
0252デフォルトの名無しさん2005/12/18(日) 21:31:18
まぁ、68000なら0代入は論理差も算術差も使わないのが常道だったわけだが。
■ このスレッドは過去ログ倉庫に格納されています