アセンブラ初心者スレッド 2©2ch.net
■ このスレッドは過去ログ倉庫に格納されています
>>513
知ってる人は自分が正しいと思うことを具体的に書けばいい。
書けないなら黙っとけと思う。 >>510じゃないけど
1.性能上(もしくはアトミック性)の理由でアラインメントを揃える
2.8086でもキャリーフラグという名前
もちろんボローの意味でも使う
フラグはOut Of Orderの妨げになりやすく
シンプルな設計を目指したRISC系では使わないし
当然SIMDでも使わない
ただし、命令を組み合わせて同じことが出来る
多倍長の加減算は(乗算他に比べて)速いので
それが性能に影響することは少ないし
64bit CPUではそもそも64bitを越えた演算をすることも非常に少ない 4.z80はまったく業界標準ではないですね
数量から言えばARMとx86系が圧倒的
MIPSは教育現場では使われるけど
数量はARMやx86系に比べたら少ない
x86も16bit命令で組む事はほぼない
32bitか64bitがほとんど いまどき初心者がZ80に興味持つはずないだろ
こいつが御高説を垂れたいがために質問を自演してるんだろ
情けない奴 Z80そのものが使われる機会は減っていてもZ80の流れを汲むアーキテクチャはまだまだある
IA32/AMD64はもちろん、ちょっと上であがっているRL78もだ >>521
そうでした
頭がMIPSと混ざってしまった 組み込み系でも8bitだと桁上がり演算でキャリーをよく使うけど32bitだと出番は激減する
32bitあれば12bitADCの変換値を10回足し込むくらいじゃ余裕
一部のアーキテクチャは特殊演算用に64bitを超えるレジスタを持っていたりするし
なおさら桁あふれしにくい >>523
ID変えて否定に回ったのが自演の証拠w Intel系のCPUは元々4bitの4004から来ている。4004は主に電卓で使われた。4bitレジスタで演算するとき
桁あふれが頻繁に起こるのがわかっていたのでキャリーフラグがあると便利だろうということで入れたんだと思う。
それが8bitの8008以降も継承されて現在に至る。だから64bitでキャリーフラグが使われないのも当然。 >>517
>ただし、命令を組み合わせて同じことが出来る
一年ほど前に調べていたら、x+y に対するキャリーフラグをC言語を使って
作り出すようなことを書いているコードを見つけた。
普通に考えればx,yの最上位ビットに着目すればいいんだけど、
最初に思いつくコードよりかなり短いコードだった。
x,yが8BITの場合、x+yに対するキャリーフラグをcfとすると、
意味的には、
cf = 0;
if ( (x & 0x80) != 0 && (y & 0x80) != 0 ) {
cf = 1;
}
でいいはずだけど、
cf = (x & y) >> 7;
かな。でも、もっとエレガントなコードだったような気がする。
何か知っていれば教えて欲しい。 さらに、x, y が符号なし8BIT整数の場合の x - y に対する carry flag については、
cf = 0;
if ( x < y ) cf = 1;
で一応求まるんだと思う。
また、sf(sign flag) に関しては、
sf = 演算結果 >> 7;
でいいと思われる。 >>530
短く書きたいのであれば、
cf = (x < y);
sf = (x - y) >> 7; >>529
cf = (x < (-y));
でも求まるかもしれない。
>>530 を書いてみて気付いた。
>>531 は逆に、
cf = (x & (-y)) >> 7;
でも行ける気がする。 >>528
64bitレジスタでは4bitレジスタに比べて桁あふれが起きにくいから使用頻度が少なくなる。 足し算
z0 = x0+y0;
z1 = x1+y1+(z0<x0);
引き算
z0 = x0-y0;
z1 = x1-y1-(z0>x0); carry = 0;
for (i=0 ; i < n ; i++){
. . if (carry){
. . . . z[i] = x[i] + y[i];
. . . . carry = z[i] < x[i];
. . }
. . else {
. . . . z[i] = x[i] + y[i] + 1;
. . . . carry = z[i] <= x[i];
. . }
} borrow = 0;
for (i=0 ; i < n ; i++){
. . if (carry){
. . . . z[i] = x[i] - y[i];
. . . . borrow = z[i] > x[i];
. . }
. . else {
. . . . z[i] = x[i] - y[i] - 1;
. . . . borrow = z[i] >= x[i];
. . }
} 自己訂正です。
実は、色々と間違いがあり、次のようになっています:
>>529 : 間違い。
530 : 正しい。
531 : 正しい。
>>532 の前半 : 正しい。
>>532 の後半 : 間違い。
改めて、>>529 の根本的な間違いとして、carry flag は、演算前の最上位ビットだけでは決まる、
というのが大間違いでした。下位ビットからの桁上がりがあるためです。
まとめると、x, y が符号なし整数の場合、
1. a = x - y に対する carry flag :
cf = (x < y);
または。
cf = (a > x);
2. a = x + y に対する carry flag :
cf = (x < (-y));
または。
cf = (a < x);
です。上記の「または」以後のやり方は、>>536 537 538 で思い出させていただきました。
一年ほど前に見たやり方がそれだったと思います。とてもエレガントですね。 MIPS64やRISC-VのRV64Iで128bit加算減算のアセンブラ出力してみると
おなじようなことやってるね
mips64 128bit加算 $4:$2 ← $5:$4 + $7:$6
daddu $2,$4,$6
sltu $8,$2,$4
dext $8,$8,0,32
daddu $3,$5,$7
daddu $4,$8,$3
mips64 128bit減算 $4:$2 ← $5:$4 - $7:$6
dsubu $2,$4,$6
sltu $8,$4,$2
dext $8,$8,0,32
dsubu $3,$5,$7
dsubu $4,$3,$8
risc-v RV64I 128bit加算 a6:a7 ← a1:a0 + a3:a2
add a7,a0,a2
sltu a6,a7,a0
add t1,a1,a3
add a6,a6,t1
risc-v RV64I 128bit減算 a1:a2 ← a1:a0 - a3:a2
sub a2,a0,a2
sgtu a0,a2,a0
sub a1,a1,a3
sub a1,a1,a0 >>525
何かいろいろ勘違いしてるようだが、キャリーフラグは条件ジャンプのときにも参照するんだぞ。
MIPSが欠陥品だと言われる理由がこれで分かるだろう。 MIPS以降の多くのRISCベースのCPUはすべてキャリーフラグがある。
とても効率的で不可欠だからだ。 >>543
Zeroフラグは良く使うがCarryフラグはほぼ使ったことがない。
どういうときに使う? フラグはアウトオブオーダーの妨げになるし
並列化も出来ないから
高速化に対してはイマイチ >>544
比較や減算で上か下か
どうやって判断してると思ってるんだよ・・・ jbという条件ジャンプ命令は使っているけど
jcという条件ジャンプ命令は使っていないので、キャリーフラグを使うことはない
アホくさ >>545
そういう嘘を真に受けてはいけない。
実際のCPU見れば並列実行能力の高い処理系はすべてキャリーフラグ持ってるし、
むしろ並列実行能力がとくに低いMIPSはキャリーフラグ持ってない。 条件分岐でキャリーフラグの使い方が分からない、使ったことがない、使われることを知らなかった、という人はなんだろう。
6502、Z80、6809、AVR、8086、68K、ARMとメジャーなCPUどれから始めてもマニュアル、入門書には書いてると思う。 JA、JB命令などは普通に使ってもJCを使うことはあまりない >>551
x86なんかキャリーフラグじゃない別のフラグを使った加算とか
歪んだ方向に行ってる
SIMDによる並列化プログラムも
フラグは単なるループ条件くらいにしか使わん
maskレジスタがその役目を継ぐ キャリーフラグを持たないアーキテクチャ・・・
MIPS?PPC?IA-64?死屍累々じゃねーかw >>545
>フラグはアウトオブオーダーの妨げになるし
>並列化も出来ないから
また嘘書いてやがる
Core iプロセッサはフラグがあってもアウトオブオーダーしまくりですが?
アウトオブオーダーを正しく理解してたら絶対にこんなことは書かない
分岐も、投機実行で大凡はカバーされるということになっている
フラグの問題は、元の機械語の並べ方に制約が生じるだけで、アウトオブオーダー実行には関係ない
アウトオブオーダーを妨げるケースでも、元のCISCの挙動に合わせるためで、アウトオブオーダーが
関係しているのではない
>SIMDによる並列化プログラムも
>フラグは単なるループ条件くらいにしか使わん
>maskレジスタがその役目を継ぐ
これもまともに理解してないからこそ書ける内容だな
Pen Proになってアウトオブオーダーが使えるようになった時にcmovが導入されたし、
「単なるループ条件」でも投機実行が必要なんだが?
ここまで酷いとお前に語る資格はないよ アウトオブオーダーの妨げの意味がわからんのだね
なんでx86に変な命令があるのか考えてみ フラグは本来依存性の無い処理まで依存性が出てくる
フラグが共通だから
レジスタのようにフラグが複数セットあって指定出来ないとダメ
そらがmaskレジスタであったりx86の変な命令であったり >>548,549
ID:YkvT9y9mがID変えたのか、別人なのかどっちだ?
アウトオブオーダーってのは、真の依存関係にない部分を抽出して同時に実行するっていう
アーキテクチャーだ
ループの2周目以降は前の分岐に依存しているから、本来は順番にしか実行できない
しかし、分岐は数値演算と違って結果のパターンが極めて限定されているので、
決め打ちで一時的に依存関係を無視して処理を進めるのが投機実行だ
アウトオブオーダー実行にはフラグレジスタの存在など関係なく、結果に依存関係が
あるかどうかが問題なんだよ
そんなことも理解せずに語ってたのかって言ってんだよ フラグを使う演算だと依存関係が出るって言ってんの
関係ない演算でもフラグのせいで依存関係が出る
同じフラグを使うから これで3回目だが...
x86の変なフラグを使う歪んだ命令は何のため? jaもjbもキャリーやゼロや符号の論理演算で表現されるのに、どうしてキャリーフラグが
どうのって話になってんの?
>>561
お前がアウトオブオーダーを理解できてないのはわかった
>フラグを使う演算だと依存関係が出るって言ってんの
>関係ない演算でもフラグのせいで依存関係が出る
>同じフラグを使うから
やはり論理レジスタと物理レジスタの理解も出来てないな
フラグを格納できるレジスタが複数あろうがなかろうが、それは命令アーキテクチャの問題であって
アウトオブオーダーの問題ではない
これでどうしてアウトオブオーダーの妨げになるんだよ?
>x86の変なフラグを使う歪んだ命令は何のため?
その変な命令って何だよ? >>552
なんか勘違いしてる。CYの使い方がわからないのではなく、使う場面が少ないからあまり意識しないんじゃないかということ。 >>564
mips64
daddu $2,$4,$6 1clock目
sltu $8,$2,$4 1clock目
dext $8,$8,0,32 2clock目
daddu $3,$5,$7 1clock目
daddu $4,$8,$3 3clock目
3clock 演算回数 計5回 (加算3回、減算1回、シフト1回)
risc-v
add a7,a0,a2 1clock目
sltu a6,a7,a0 1clock目
add t1,a1,a3 1clock目
add a6,a6,t1 2clock目
2clock 演算回数 4回 (加算3回、減算1回)
amd64
add 1clock目
adc 2clock目
2clock 演算回数 2回(加算2回)
mips、risc-vは必死に並列化してるのに速くならない。
むしろキャリーがあったほうが無駄な演算回数が減り消費電力も減り、
演算器に空きができ、他の計算の余力を得ることになり、並列処理能力は上がることが分かる。
キミのいう依存関係が出てmipsのほうが速い例を挙げてほしい。 >>556
最近巷をさわがせてるRISC-Vもキャリーフラグはないぞ
今あるCPUの中で最も新しいアーキテクチャなんだが MIPSの話が出るとすぐにキャリーフラグを連呼する例の人かな
彼は8bitCPUの話が好きみたいだが
もう、既に死んでる6502、Z80、6809、68Kあたりを挙げてるからすぐにわかる 8bitCPUなら多倍長演算はよく使うだろうが64bitCPUではほぼ出番がない >>568
> 関係ない演算でもフラグのせいで依存関係が出る
RISC-V信者さんって大学の人でしょ? 例を出してよ。どんな演算? RISC-VならARMのCortex-A72より早いコアができたってさ
このクラスの性能のCPUはx86、POWER、ARM以外にないだろうに
SiFive readies U8-Series RISC-V core designs to compete with ARM's Cortex-A72 models
https://www.notebookcheck.net/SiFive-readies-U8-Series-RISC-V-core-designs-to-compete-with-ARM-s-Cortex-A72-models.440633.0.html >>571
別人の発言なのに敵視した人は誰でも同一人物だと思っちゃう人? >>573
> フラグはアウトオブオーダーの妨げになるし並列化も出来ないから
> 変なフラグを使う歪んだ命令は何のため?
逃げてばかりいないでどういうことか説明してくれよ。コード例がひとつも出ないってどういうことだよ。
128bit加算ではMIPSのほうが遅くなってるし。これ依存関係のない128bit加算が複数あったら
パイプラインが先に詰まるのは演算回数の多い、MIPS、RISC-Vじゃん。>>566 RISC-Vの中国製チップを使ったマイコンボード手に入れたが、
普通にCortex-A7クラスのIPCがあってびっくりした
ARMと違ってRISC-Vなのでおそらく中国の半導体メーカーがコアの設計までしたんだろうな
RISC-Vならオープンソースのコアがあるから
中国の半導体メーカーでもそれを参考にして設計できるんだろうね
RISC-Vは中国やインドで推進してるから今後普及していくだろうね SIMD命令にキャリーフラグやADC/SBB/RCR/RCL命令が無いのが
演算としては使わないっていう証拠
こういった命令は昔のチープな環境のなごり >>574
たとえば、
CMP EAX,10
JB hogehoge
こんなコードだと比較命令でフラグレジスタが変わるが
次の命令ですぐにフラグレジスタを参照してるってことじゃないの?
俺が発言したわけじゃないから知らんけど >>577
mips、risc-vも依存して並列実行できない例を出されてもだな。
しかも投機実行されるintelx64のほうがさらに速くて、mips、risc-vはストールする例だし。 >>578
x86だと演算命令で必ずフラグの値が変わるので
比較命令とジャンプ命令の間にフラグの値が変わるようなほかの命令を挟めないからね そもそもキャリーフラグが有用なのは2進バイナリの多倍長演算の時だけ
64bitCPUではほぼ出番がない 挟むめないって挟む理由あるアルゴリズムなんて存在するか?
そんなコード書ける高級言語はないし。キミは一体RISCで何を計算したいんだ? アセンブラの話してるのになんで高級言語の話になるのかな?
MIPSならslt $2, $3, 11とジャンプ命令の間にほかの命令を挟めるってこと >>582
そうではない。挟まなきゃならない理由を聞いている。
それで並列化できなかったものが並列化可能なら例になるがそうではない。判定の前に命令書いても依存関係がなければ並列化される。
キミの例は可読性が悪くなる書き方ができるというだけで並列化できる例ではない。むしろMPSの欠点だ。
> フラグはアウトオブオーダーの妨げになるし並列化も出来ないから
の例を聞いてるんだよ。ひとつも例が出せてないじゃないか。 演算のたびにフラグレジスタが変化するのは無駄だとは思うけどね
特にアドレス計算のたびにフラグレジスタが変化するのはうっとうしい
ARMだと加算減算命令はフラグレジスタが変化するものと変化しないのと2種類用意されてるね しかし、キャリーフラグの話題でここまでスレ伸ばすのはすごいね
8bitのAVR信者っぽいんだけど
8bitだとキャリーフラグがないと何もできないからね 結局、自分から言い出しといて挟まなきゃならない理由も説明してくれないのか。
まだほとんどコード書いたことない初心者なんだね^^ 間に挟みたい場面なんていくらでもあるだろうに
少しは考えたら? >>587
自分で言い出しといて、答え、コード例は絶対に言わないのね。
そりゃコード書かないもんね、大学の人は。初心者だもん。 パイプラインがストールするとか言うから
MIPSやRISC-Vならslt命令とbne命令の間に他の命令を挟めるよと言っただけ
自分で発言を誘っておいて意味もわからないんだな >>589
頓珍漢。ストールするのは条件ジャンプだから。挟んでもその後でmipsはストールする。
挟まなきゃならない理由の説明になってなし、並列化できるでなきいの例でもなんでもない。
話戻すよ。mipsは並列化できてフラグありCPUで並列化できない例を挙げてと言ってるんだよ。 まあ、いつものAVRの人の荒らしだからまともに答えるだけ無駄 >>591
たった一つの例が全然例でなかったのに勝利宣言か。だいたいAVRもキミの好きなRISCだろう。
cmp
jb
並列化できない!! ←mipsでもできません
cmp
add
jb
mipsならこんなことができる!!
↑
挟む理由は別になし。可読性が低下するだけ。
同じことしたいならadd、cmp、jbの順に書けばいいだけ。これで並列可。
しかもmipsのほうが遅いという。 cmpに時間がかかる(可能性がある)なら挟む
分岐なのでcmp結果はなるべく早く欲しい
当然命令順が速い方が実行順が速い可能性が高くなる
アセンブラに可読性?
99.99%のコードはコンパイラを使うから
そもそも可読性を考えて命令を作らない キャリーフラグの典型的な用途
多倍長整数の加算
ADCを連続で行うが
この間にキャリーフラグを使う命令は入れられない
今時のCPUは整数命令を4個同時に実行出来るので
間に命令をいれないと性能の1/4しか活かせない
性能を活かすには4個パラにするか、
多倍長加算以外の処理を入れることになるが
キャリーフラグのせいでこれが出来ない
最大限に最適化する場合はSIMD命令を使うのだが
これにもキャリーフラグなんてものは無い 現状RISC-Vの性能はAMD64に及ばなくね?理論がどうであれ実証できなきゃ絵に描いた餅よ
IA-32は長らくクソと言わ続けているがIntelとAMDが競争しているおかげか
そのハンデをねじ伏せいまだに高性能プロセッサの一角だしな こんな極端な例じゃなくても
実際の実行順に近い順番で命令を書く方が
アウトオブオーダーの制約に引っ掛かりにくく
性能を活かせやすい
実際の実行順で
キャリーフラグを変更する命令と
キャリーフラグを使う命令
の間に何も命令を実行しないなんてことは非常にマレ
あったとすれば、
それはCPUの能力を全く活かしてない糞コード >>595
> cmpに時間がかかる(可能性がある)なら挟む
また理由は書かないのか。まあ理由は分からないがMIPSはそんな可能性があるとは遅くて大変だな。
インテルの実装は速くなることはあっても遅くはならないから。いつになったらフラグで遅くなる例を出してくれるんだか。
まさか条件分岐でインテルやARMに勝つ気じゃないよね? MIPS vs ARM (またはx86) だと思ってる時点で話にならん >>600
煽る暇があったらフラグで遅くなる例をひとつぐらい出してよ。
128bit加算も条件分岐も全部MIPSのほうが遅い例ばかりじゃん。 いつものAVR信者だからかまっちゃダメ
MIPSと聞くと毎回同じようにキャリーフラグの話を始める
いつも自分が正義だと思い込んでて他人の都合の悪い意見は全く無視するからね
http://rio2016.5ch.net/test/read.cgi/denki/1462177958/134
134 :774ワット発電中さん [↓] :2019/11/30(土) 14:53:33.69 ID:IRFNBB8m.net
またMIPS君が他の板で暴れて論破された模様TT
フラグで遅くなる例を出せと言われて一つも出せなかったらしい。 >>574
そりゃ逃げ回るでしょ、アウトオブオーダーがどんな仕組みで並列に実行できるのか理解してないんだからw
こんなこと書いてるからな
>フラグは本来依存性の無い処理まで依存性が出てくる
>フラグが共通だから
これのどこがアウトオブオーダーによる制限なんだよw
間に挟めないのは元の命令アーキテクチャによる制限だって書いたよな
>>596
>今時のCPUは整数命令を4個同時に実行出来るので
>間に命令をいれないと性能の1/4しか活かせない
また出まかせをw
ここ数年インテルがリオーダーバッファのサイズとか強化してるのは何でだよ?
メモリアクセスのレイテンシの影響を軽減するためだろ
そういう状態ではカウンタとかポインタのインクリメントみたいな処理は前倒しで実行されるから、
間に命令を挟んだのと同じことになるよな 分岐に必要な命令を先に実行するほど頭は良くない
単に実行出来る命令から実行するだけ
だからコンパイラがわざわざ順番を変える
フラグのせいでそれに大きな制限がつく
アウトオブオーダーが完璧ならコンパイラがわざわざ順番を変えたりループを展開したりしないから
同じ命令を使えば誰が書いても同じパフォーマンス
そこまで時代は進んでない
だからCコードで最適化してコンパイラが最適化してCPUが最適化してるの
フラグは8bitとか16bitとか、
非常に規模の小さなCPUにとっては便利だが
規模の大きなCPUでは足かせになる
使用頻度は減って
使用用途はほとんど分岐くらい
レジスタの数も少ないと問題だろ?
フラグも同じ で >>596 の話
ADCを続けるのにどうやって他の命令を実行する?
そもそも記述が出来ない
1000回ADCを行うなら
その間にフラグ更新命令を一切記述出来ない
CPUの最適化以前の問題 RCR/RCL による多倍長の1ビットシフトなんか最悪だ
依存性が途切れないので1クロックに1回しか出来ない
ADCもSBBも依存性が途切れないから
もっと頭の良い方法を使うんだけど まあそもそも可読性とか言ってる時点で話にならん
アセンブラなんか使わないで素直にCで書いてな ID:zk5zlAHcはID:4DEcYZGMやID:zk5zlAHcなんて擁護すると見識を疑われるぞ!
>>604
うわっ、酷っ!
>レジスタの数も少ないと問題だろ?
>フラグも同じ
結局これしか理解できてないから壮大な妄想を展開してたのかよw ID:4DEcYZGMとID:WebQyLi7
だった 大体、
普段多倍長なんか使わんだろ
頻繁に演算でフラグを使う場面ていつだよ?
64bitありゃ99%は問題ないだろ
フラグの用途のほとんどが条件分岐だろうが
SIMDにフラグが無い理由を少しは考えろ >>606
>RCR/RCL による多倍長の1ビットシフトなんか最悪だ
>依存性が途切れないので1クロックに1回しか出来ない
これも突っ込みどころのある発言w
どうして依存性が切れないのか、やっぱり理解できてない 1000ワードの多倍長加算を100個
データはキャュシュにあるとして
どんなコードにする?
糞遅いコードしか書けないだろうね ■ このスレッドは過去ログ倉庫に格納されています