なぜx86は醜いのですか?他の人と比較して、なぜ劣っているのですか?[閉まっている]


105

最近、私はいくつかのSOアーカイブを読んでいて、x86アーキテクチャに対するステートメントに遭遇しました。

のような多くのコメント

検索してみましたが、理由はわかりませんでした。これが私がよく知っている唯一のアーキテクチャであるため、x86が悪いとは思わない。

他の人と比較してx86を醜い/悪い/劣っていると考える理由を誰かが親切に教えてくれますか?


1
私はこれまでの答えに基づいてS&Aを進めていますが、CISCはm68k命令セットの問題ではないことを指摘しておきます。x86はそれであり、あなたはそれを保つことができます。
dmckee ---元モデレーターの子猫2010

「S&A」とは?「CISCはm68k命令セットの問題ではありません。」 - 何故なの?

5
motorala 68000シリーズチップは、高度なCISCアーキテクチャを備えていますが、均一でかなり直交しており、非常に簡単な命令セットを備えています。なぜx86と違うのですか?知りません。ただし、チップの複雑さと命令セット(つまり、アセンブリプログラマーが見るインターフェイス)の複雑さとの間には大きな違いがあることに注意してください。
dmckee ---元モデレーターの子猫2010

4
非常に興味深い質問の+1。
チューリング完了

1
CISCおよびRISC設計の原動力となったものについての良い議論を含む、ここにあるさまざまなプロセッサーのエネルギー効率に関する最近の研究。extremetech.com/extreme/...

回答:


93

考えられる理由は次のとおりです。

  1. x86は比較的古いISAです(結局、その祖先は8086年代でした)
  2. x86は大幅に進化していますが、古いバイナリとの下位互換性を維持するにはハードウェアが必要です。たとえば、最新のx86ハードウェアには、ネイティブで16ビットコードを実行するためのサポートがまだ含まれています。さらに、リアルモード、プロテクトモード、仮想8086モード、および(amd64)ロングモードなど、古いプロセッサが同じプロセッサ上で相互運用できるように、いくつかのメモリアドレス指定モデルが存在します。これは一部のユーザーを混乱させる可能性があります。
  3. x86はCISCマシンです。長い間、これはMIPSやARMなどのRISCマシンよりも遅いことを意味していました。命令にはデータの相互依存性とフラグがあり、ほとんどの形式の命令レベルの並列処理を実装することが困難だからです。最新の実装では、x86命令を「マイクロオペレーション」と呼ばれるRISCのような命令に変換して、これらの種類の最適化をハードウェアに実装することを実用的にしています。
  4. いくつかの点で、x86は劣っていません。ただ違うだけです。たとえば、入力/出力は、大部分のアーキテクチャではメモリマッピングとして処理されますが、x86では処理されません。(注:最近のx86マシンは通常、何らかのDMAサポートを備えており、メモリマッピングを介して他のハードウェアと通信しますが、ISAにINやなどのI / O命令がまだありますOUT
  5. x86 ISAには非常に少数のアーキテクチャレジスタがあり、プログラムがメモリを必要以上に頻繁にラウンドトリップするように強制できます。これを行うために必要な追加の指示は、効率的なストア転送ではありますが、有用な作業に費やす可能性がある実行リソースを必要としますレイテンシを低く保ちます。大きな物理レジスタファイルにレジスタの名前を変更する最新の実装では、多くの命令を実行できますが、アーキテクチャレジスタの欠如は、32ビットx86の重大な弱点でした。x86-64の8から16への整数およびベクトルレジスタの増加は、64ビットコードの最大の要因の1つであり、32ビットよりも高速です(より効率的なレジスタ呼び出しABIとともに)。各レジスタの幅の増加ではありません。16から32の整数レジスターをさらに増やすと、一部では役立ちますが、それほど効果はありません。(ただし、浮動小数点コードはレイテンシが高く、多くの定数が必要になることが多いため、AVX512は32のベクトルレジスタに増加します。)(コメントを参照
  6. x86は多くの機能を備えた複雑なアーキテクチャであるため、x86アセンブリコードは複雑です。典型的なMIPSマシンの指示リストは、1文字のサイズの紙に収まります。x86の同等のリストはいくつかのページを占めており、指示はより多くのことを行うので、多くの場合、リストが提供できるよりも大きな説明を必要とします。たとえば、MOVSB命令には、その機能を説明するために比較的大きなCコードのブロックが必要です。

    if (DF==0) 
      *(byte*)DI++ = *(byte*)SI++; 
    else 
      *(byte*)DI-- = *(byte*)SI--;
    

    これは、ロード、ストア、および2つの加算または減算(フラグ入力によって制御)を実行する単一の命令であり、それぞれがRISCマシン上の個別の命令になります。

    MIPS(および類似のアーキテクチャー)の単純さは必ずしも優れているわけではありませんが、アセンブラークラスの概要を教えるには、単純なISAから始めるのが理にかなっています。一部のアセンブリクラスは、y86と呼ばれるx86の非常に簡略化されたサブセットを教えます。これは、実際の使用には役に立たない(シフト命令がないなど)点を超えて簡略化されているか、基本的なx86命令のみを教えます。

  7. x86は可変長のオペコードを使用するため、命令の解析に関してハードウェアが複雑になります。現代では、CPUが未処理の計算よりもメモリ帯域幅によってますます制限されるようになると、このコストは非常に小さくなりますが、多くの "x86バッシング"記事および態度は、このコストが比較的はるかに大きかった時代から来ています。
    2016年更新:Anandtechは、x64およびAArch64でのオペコードサイズに関するディスカッションを投稿しました。

編集:これはx86のbashではありませんパーティー。質問の言い方を考えると、私には選択の余地がほとんどありませんでした。しかし、(1)を除いて、これらすべては正当な理由で行われました(コメントを参照)。インテルのデザイナーは愚かではありません。彼らは自分たちのアーキテクチャーでいくつかのことを達成したかったのですが、これらはそれらを実現するために払わなければならない税金の一部です。


17
それはトレードオフです。これは、バイナリサイズが小さくなる可能性があるという長所ですが、これらの命令のパーサーを実装するには非常に複雑なハードウェアが必要になるという弱点があります。命令の大部分はとにかく同じサイズです-x86で可変長オペコードを使用する理由のほとんどは、機能を追加することを決定し、処理する必要のあるビット数で必要なものを表現できないことが判明したためです。 。大多数の人々は、ハードウェアの複雑さや電力消費とほぼ同じくらいバイナリサイズに関心がありません。
ビリーONeal 2010

8
@Joey Adams:x86の可変長命令をARMの親指モード(en.wikipedia.org/wiki/ARM_architecture#Thumb)と比較してください。Thumbモードでは、短い命令が通常の命令に直接マップされるため、ARMのオブジェクトコードが大幅に小さくなります。しかし、大きな命令と小さな命令の間には1:1のマッピングがあるため、解析ハードウェアの実装は簡単です。x86の可変長命令は、そもそもそのように設計されていないため、これらの利点はありません。
ビリーONeal 2010

7
(6)すべてのオペコードがすべてのプログラムで使用される必要があるわけではありませんが、SSE3が必要なとき、私はそれを手に入れてよかったと思います。
Chris K

4
@Chris Kaminski:それはハードウェアにどのような影響を与えませんか?もちろん、現代のフルサイズのコンピュータでは誰も気にしませんが、携帯電話のようなものを作っている場合、私はほとんど何よりも電力消費量に関心があります。可変長オペコードは実行時間を増加させませんが、デコードハードウェアは動作するために電力を必要とします。
ビリーONeal

5
これは、x86命令セットを非常に醜くする原因の1つです。これは、それがアキュムレータであるか、レジスタファイルベースのアーキテクチャであるかを判断できないためです(ただし、これは、ほとんどの場合、命令セットをより直交させる386で修正されました)。 、68kのファンがあなたに言ったことに関係なく)。
ninjalj 2011

25

私の心の中でx86に対する主なノックはCISCの起源です-命令セットには多くの暗黙的な相互依存関係が含まれています。これらの相互依存性のアーティファクトとセマンティクスは各命令で保存する必要があるため、これらの相互依存性により、チップ上での命令の並べ替えなどを行うことが困難になります。

たとえば、ほとんどのx86整数加算および減算命令はフラグレジスタを変更します。加算または減算を実行した後の次の操作は、フラグレジスタを調べてオーバーフローや符号ビットなどを確認することです。その後に別の加算がある場合、2番目の加算の実行を開始しても安全かどうかを判断するのは非常に困難です。最初の追加の結果がわかる前に。

RISCアーキテクチャでは、add命令は入力オペランドと出力レジスタを指定し、操作に関するすべてのことはそれらのレジスタのみを使用して行われます。これにより、すべてを整列して単一のファイルを実行するように強制するbloomin 'フラグレジスタがないため、互いに近い追加操作を簡単に分離できます。

MIPSスタイルのRISC設計であるDEC Alpha AXPチップは、使用可能な命令が非常に質素でしたが、命令セットは、命令間の暗黙的なレジスタ依存関係を回避するように設計されていました。ハードウェア定義のスタックレジスタはありませんでした。ハードウェア定義のフラグレジスタはありませんでした。命令ポインタもOSで定義されていました。呼び出し元に戻りたい場合は、呼び出し元がどのアドレスに戻るかを通知する方法を考え出す必要がありました。これは通常、OS呼び出し規約によって定義されました。ただし、x86では、チップハードウェアによって定義されます。

とにかく、3世代または4世代のAlpha AXPチップデザインでは、ハードウェアは、32個のintレジスタと32個のfloatレジスタを備えたスパルタン命令セットの文字通りの実装から、80個の内部レジスタを備えた大規模に順序が乱れた実行エンジン、レジスタ名の変更、結果の転送(前の命令の結果が、値に依存する後の命令に転送される)およびあらゆる種類のワイルドでクレイジーなパフォーマンスブースター。そして、それらすべての口笛により、AXPチップのダイは、当時の同等のペンティアムチップダイよりもかなり小さく、AXPははるかに高速でした。

x86命令セットの複雑さにより、多くの種類の実行の最適化が不可能ではないにしても法外に高価になるため、x86ファミリーツリーでこれらの種類のパフォーマンスの急増を見ることはほとんどありません。Intelの天才的な一撃は、x86命令セットをハードウェアに実装することをあきらめることでした-すべての現代のx86チップは実際にはある程度までx86命令を解釈するRISCコアであり、それらを元のx86のすべてのセマンティクスを保持する内部マイクロコードに変換します命令ですが、そのRISCの少し順序が狂っていたり、マイクロコードに対するその他の最適化が可能です。

私は多くのx86アセンブラを記述しており、そのCISCルートの利便性を十分に理解できます。しかし、Alpha AXPアセンブラを書くのにしばらく時間を費やすまで、私はx86がどれほど複雑であるかを十分に理解していませんでした。私はAXPのシンプルさと均一性にうんざりしていました。違いは非常に大きく、深遠です。


6
m68kについて説明できるまでは、CISC 自体のバッシングは聞かないでしょう。
dmckee ---元モデレーターの子猫2010

2
私はm68kに慣れていないので、批評することはできません。
dthorpe、2010

4
私はこの回答が反対票を投じるのに十分悪いとは思わないが、「RISCはCISCより小さくて速い」という議論全体は現代ではあまり関係がないと思う。確かに、AXPは今のところずっと速い地獄だったかもしれませんが、問題の事実は、パフォーマンスに関しては、現代のRISCと現代のCISCがほぼ同じであることです。私の回答で述べたように、x86デコードのわずかな電力ペナルティは、携帯電話のようなものにx86を使用しない理由ですが、それはフルサイズのデスクトップまたはノートブックではほとんど議論の余地がありません。
ビリーONeal

4
@ビリー:サイズは、単なるコードサイズや命令サイズではありません。Intelは、これらすべての特別な命令のハードウェアロジックを実装するために、チップの表面積にかなりのペナルティを支払っています。ダイのサイズは製造コストに直接影響するため、最新のシステム設計では依然として問題となっています。
dthorpe、2010

1
@dthorpe:私はあなたが書いたもののすべてではないにしてもほとんどに同意しません。今まで8086以来、あなたはそれを実行しても安全であれば心配する必要はありませんでしたadd別の後にadd。ルールは明確です。また、命令の並べ替えに対処する必要もありません。90年代半ばのPentium Pro以来、CPUがそれを代行してくれます。あなたが言っていることは20年前の問題であったかもしれませんが、今日x86アーキテクチャに対してそれを保持する理由を私は見ていません。
Nathan Fellman、2013年

21

x86アーキテクチャは、8008マイクロプロセッサとその関連製品の設計に由来します。これらのCPUは、メモリが遅いときに設計されたもので、CPUダイで実行できる場合は、はるかに高速でした。ただし、CPUダイスペースも高価でした。これらの2つの理由は、特別な目的を持つ傾向があるレジスタの数が少なく、あらゆる種類の問題や制限がある複雑な命令セットがある理由です。

同じ時代の他のプロセッサ(6502ファミリなど)にも同様の制限と癖があります。興味深いことに、8008シリーズと6502シリーズの両方が組み込みコントローラーとして意図されていました。その当時でさえ、組み込みコントローラーはアセンブラーでプログラムされ、コンパイラーライターではなくアセンブリプログラマーに提供されることが多くの方法で期待されていました。(コンパイラーの書き込みに応じたときに何が起こるかについては、VAXチップを見てください。)設計者は、それらが汎用コンピューティングプラットフォームになることを期待していませんでした。それが、POWERアーキテクチャーの前身のようなもののためのものでした。もちろん、ホームコンピューター革命はそれを変えました。


4
問題の歴史的背景を実際に持っていると思われる人からの唯一の回答の+1。
ビリー・オニール

3
メモリは常に遅いです。1982年にZ80とCP / Mで始めたときよりも、今日は(相対的に言えば)遅くなる可能性があります。特定の進化の方向が止まるという絶滅により、絶滅は進化の唯一の道ではありません。x86は、28年間(これまでの存在)で順応しています。
Olof Forshell、2010

4
メモリ速度は、8086の頃にCPUとほぼ同等に短時間ヒットしました。TexasInstrumentsの9900は、これが発生したためにのみ機能する設計になっています。しかし、その後、CPUは再び先を争い、そこにとどまっています。現在、これを管理するのに役立つキャッシュがあります。
staticsan

3
@Olof Forshell:8080アセンブリコードを8086コードに変換できるという点でアセンブラ互換でした。その観点からは、8080以上の拡張機能であり、8080を8008以上の拡張機能と見なすことができます。
David Thornley、2011年

3
@Olof Forshell:8086がそのために設計されたことを除いて。これは8080の拡張であり、明らかに(おそらくすべて)8080の命令は1対1でマッピングされ、セマンティクスは明らかに類似しています。それをどの方法でプッシュしたいかに関係なく、これはIBM 360アーキテクチャーには当てはまりません。
David Thornley、2011

13

ここにいくつかの追加の側面があります:

操作 "a = b / c"を考えると、x86はこれを次のように実装します。

  mov eax,b
  xor edx,edx
  div dword ptr c
  mov a,eax

div命令の追加ボーナスとして、edxには残りが含まれます。

RISCプロセッサでは、最初にbとcのアドレスをロードし、メモリからレジスタにbとcをロードし、除算してaのアドレスをロードしてから、結果を保存する必要があります。Dst、src構文:

  mov r5,addr b
  mov r5,[r5]
  mov r6,addr c
  mov r6,[r6]
  div r7,r5,r6
  mov r5,addr a
  mov [r5],r7

ここでは通常、残りはありません。

ポインタを介して変数をロードする場合は、両方のシーケンスが長くなる可能性がありますが、すでに別のレジスタに1つ以上のポインタがロードされている可能性があるため、RISCの可能性は低くなります。x86はレジスターが少ないため、ポインターがそれらの1つにある可能性は小さくなります。

長所と短所:

RISC命令は、命令のスケジューリングを改善するために周囲のコードと混合される場合があります。これは、代わりにCPU自体の内部でこのシーケンスを実行する(シーケンスによっては多かれ少なかれ)x86では可能性が低くなります。上記のRISCシーケンスは、32ビットアーキテクチャでは通常28バイト長(32ビット/ 4バイト幅の7つの命令)になります。これにより、命令のフェッチ(7回のフェッチ)時にオフチップメモリ​​がより効率的に動作します。より高密度のx86シーケンスには含まれる命令の数が少なく、その幅はさまざまですが、平均で4バイト/命令も表示されていると思います。これを高速化するための命令キャッシュがある場合でも、7回のフェッチは、x86と比較して、他の場所で3回の不足分を補うことを意味します。

保存/復元するレジスターが少ないx86アーキテクチャーは、おそらくRISCよりもスレッド切り替えを行い、割り込みをより速く処理することを意味します。保存および復元するレジスターが増えると、割り込みを行うための一時的なRAMスタックスペースと、スレッドの状態を保存するための永続的なスタックスペースが必要になります。これらの側面により、x86は純粋なRTOSを実行するためのより良い候補になるはずです。

もっと個人的には、RISCアセンブリをx86よりも書くのは難しいと思います。これを解決するには、CでRISCルーチンを記述し、生成されたコードをコンパイルして変更します。これは、コード生成の観点からはより効率的であり、実行の観点からはおそらくあまり効率的ではありません。追跡するこれらの32のレジスタすべて。x86の場合は逆になります。「実際の」名前の6〜8個のレジスタを使用すると、問題が管理しやすくなり、生成されたコードが期待どおりに機能するという信頼が高まります。

醜い?それは見る人の目にあります。「違う」を好む。


私の例のa、b、cは、メモリベースの変数として見なされるべきであり、即値ではありません。
Olof Forshell 2010

... "dword ptr"は、たとえば、サイズが不明な変数のサイズを指定するために使用されます。たとえば、単純に外部として宣言されている場合や、怠惰な場合です。
Olof Forshell、2010

2
最初にCで記述してから、アセンブラーに蒸留するという提案を聞いたのは、これが初めてではありません。それは間違いなく役立ちます
Joe Plante 2014

当初、すべてのプロセッサはRISCでした。CISCは、速度が非常に遅く、より強力な命令が少なく、メモリサブシステムへのストレスが少なく、帯域幅をより有効に活用できる、鉄コアメモリシステムの緩和戦略として生まれました。同様に、レジスターは元々、累積を行うためのオンチップ、CPU内のメモリー位置と考えられていました。最後にRISCマシンを真剣に評価したのは1993年で、SPARCとHP Prisimでした。SPARCは全体的に恐ろしいものでした。Prisimは、add / sub / mulで486の最大20倍の速さでしたが、超越的なものでは劣っていました。CISCの方が優れています。

@OlofForshellあなたは言うthere typically won't be a reminderが、wikiはミップにそれがあると言っています:en.wikipedia.org/wiki/MIPS_instruction_set#Integer
Alex Zhukovskiy

10

この質問には誤った仮定があると思います。x86を醜いと呼ぶのは、主にRISCにこだわった学者だけです。実際には、x86 ISAは、RISC ISAで5〜6命令を実行する単一の命令操作で実行できます。RISCファンは、現代のx86 CPUがこれらの「複雑な」命令をマイクロオペレーションに分解することに反対するかもしれません。しかしながら:

  1. 多くの場合、それは部分的にのみ当てはまるか、まったく当てはまりません。x86で最も有用な「複雑な」命令は、mov %eax, 0x1c(%esp,%edi,4)すなわちアドレス指定モードなどであり、これらは分解されません。
  2. 最近のマシンでしばしばより重要なのは、費やされたサイクル数ではなく(ほとんどのタスクはCPUバウンドではないため)、コードの命令キャッシュへの影響です。5-6の固定サイズ(通常は32ビット)の命令は、まれに5バイトを超える複雑な命令よりもキャッシュに大きな影響を与えます。

x86は、約10〜15年前にRISCのすべての優れた側面を本当に吸収しており、RISCの残りの品質(実際には、定義するもの-最小の命令セット)は有害で望ましくありません。

CPUの製造のコストと複雑さ、およびそれらのエネルギー要件は別として、x86は最高のISAです。そうでなければあなたに言う誰もがイデオロギーや議題を彼らの推論の邪魔にさせています。

一方、CPUのコストが重要視される組み込みデバイス、またはエネルギー消費が最大の関心事である組み込み/モバイルデバイスをターゲットにしている場合、ARMまたはMIPSはおそらくより意味があります。ただし、簡単に3〜4倍のコードを処理するために必要な追加のRAMおよびバイナリサイズに対処する必要があり、パフォーマンスに近づくことはできません。これが問題になるかどうかは、何を実行するかによって大きく異なります。


3
エネルギー消費が最大の関心事である場合、ARMまたはMIPSはおそらくより理にかなっています...したがって、ARMまたはMIPSがより意味がある少なくとも1つの側面がある場合、x86 が必ずしも最高のISAになるとは限りませんか?
Shahbaz 2013

だからこそ、私は「最高のもの」を「コストとは別に、そしてそれらのエネルギー要件」を除いて認定しました。
R .. GitHub ICE HELPING ICEを停止する

1
IntelはCPU速度を抑えており、ダイのサイズが小さいほど、電力の差はほとんどなくなったと思います。64k L1および1MB L2キャッシュを備えた新しいCeleronデュアル64ビットCPUは、7.5ワットのチップです。それは私の「スターバックス」ハングアウトマシンであり、バッテリーの寿命は途方もなく長く、P6マシンの周りでリングが鳴ります。主に浮動小数点計算をしている人として、ずっと前にRISCをあきらめました。クロールするだけです。特にSPARCはひどい氷河でした。RISCがひどい理由の完璧な例はIntel i860 CPUでした。インテルは二度とそこに行きませんでした。

@RocketRoy:7.5ワットは、24時間年中無休で(および、有用な計算を常時実行していない)または3.7v / 2000mAhバッテリーで動作しているデバイスには実際に受け入れられません。
R .. GitHub ICE HELPING ICEの停止2014

2
@RocketRoy 「Intel i860CPU。Intelが二度とそこに行ったことはありません。」少し調べてみると、i860はItaniumによく似ています。VLIW、コンパイラー命令の命令並列処理...
Jonathon Reinhart

9

x86アセンブラー言語はそれほど悪くありません。マシンコードにたどり着いたとき、それは本当に醜くなり始めます。命令のエンコーディング、アドレス指定モードなどは、ほとんどのRISC CPUのものよりもはるかに複雑です。そして、後方互換性のために組み込まれた追加の楽しみがあります-プロセッサーが特定の状態にあるときにのみ作動するものです。

たとえば、16ビットモードでは、アドレッシングは実に奇妙に見えます。にはアドレス指定モードがありますが[BX+SI]、にはありません[AX+BX]。必要に応じて使用できるレジスターに値を確実に入れる必要があるため、このようなことはレジスターの使用を複雑にする傾向があります。

(幸いなことに、32ビットモードはより健全です(まだ少し奇妙な場合もあります-たとえば、セグメンテーションなど)。また、16ビットx86コードは、ブートローダーや一部の組み込み環境以外ではほとんど関係ありません。)

Intelがx86を究極のプロセッサにしようとしていた昔からの残り物もあります。命令が実際にこれ以上誰も実行しないタスクを実行する数バイトの長さであったため、率直に言って、速度が速すぎたり複雑すぎたりしていました。2つの例のENTERおよびLOOP命令 -Cスタックフレームコードは「push ebp; mov ebp、esp」のようなものであり、ほとんどのコンパイラでは「enter」ではないことに注意してください。


2
一部のプロセッサでは「push / mov」の方が速いため、「enter」対「push / mov」の問題が発生したと思います。一部のプロセッサでは、「Enter」の方が高速です。C'est la vie。
ディートリッヒエップ2010

4
x86ベースのマシンに強制され、それを調べ始めたとき(m68kのバックグラウンドを持っている)、私はasmプログラミングに苛立ちを感じ始めました...まるでCのような言語でプログラミングを学んだようになり、 asmとの接触を強いられる...あなたは、表現力、使いやすさ、明瞭さ、「一貫性」、「直感性」の力を失う「感じる」。x86でasmプログラミングを始めたとしたら、きっとそれはそれほど悪くはありません...多分...私はMMIXとMIPSも行いました、そしてそれらの "asm lang"はx86よりもはるかに優れています(これがQの適切なPoVである場合、そうでないかもしれません)
ShinTakezou

アドレッシングモードの問題は80386で修正されました。アドレッシングモードが制限されているのは16ビットコードのみで、32ビットコードの方がはるかに優れています。特別なプレフィックスを使用して、16ビットコードで32ビットアドレッシングモードを取得できます。
fuz

@FUZxxl:うん...私はおそらく醜さはに16ビットコードに限定されていると述べるべきだった。修正済み(私は思う)。:)
cHao

知覚されたエレガンスは、ほとんどの場合、8086のレジスタは汎用レジスタであるという誤解から生じます。それは間違っています。それぞれに特別な目的があり、それらの目的に固執しないと、あなたは悪い時間を過ごすことになります。
fuz

3

私は専門家ではありませんが、人々がそれを好まない理由の多くが、それがうまく機能する理由である可能性があるようです。数年前、(スタックの代わりに)レジスター、レジスター・フレームなどを使用することは、アーキテクチャーを人間にシンプルに見せるための優れたソリューションと見なされていました。ただし、最近では、重要なのはキャッシュのパフォーマンスであり、x86の可変長ワードを使用すると、より多くの命令をキャッシュに格納できます。「命令デコード」は、反対者がチップの半分を占めたと指摘したと私は信じていますが、もはやそれほど多くはありません。

並列処理は、今日最も重要な要素の1つだと思います-少なくとも、すでに十分に高速で使用できるアルゴリズムの場合はそうです。ソフトウェアで高度な並列処理を表現すると、ハードウェアがメモリレイテンシを償却(または多くの場合完全に非表示)できます。もちろん、さらに遠くまで到達するアーキテクチャの未来は、おそらく量子コンピューティングのようなものです。

私はnVidiaから、Intelの過ちの1つがバイナリ形式をハードウェアの近くに保持していたことであると聞きました。CUDAのPTXはいくつかの高速レジスタ使用計算(グラフの色付け)を行うため、nVidiaはスタックマシンの代わりにレジスタマシンを使用できますが、古いソフトウェアをすべて壊すことのないアップグレードパスがあります。


9
RISCは人間の開発者を念頭に置いて設計されていません。RISCの背後にあるアイデアの1つは、アセンブリの作成者、理想的にはコンパイラーにチップの複雑さの一部を任せることでした。レジスタが多いほど、メモリ使用量が少なくなり、命令間の依存関係が少なくなるため、パイプラインが深くなり、パフォーマンスが向上します。x86-64には、x86の2倍の汎用レジスターがあり、これだけでパフォーマンスが大幅に向上することに注意してください。また、ほとんどのx86チップの命令は、キャッシュされる前ではなく、キャッシュされる前にデコードされます(サイズはここでは関係ありません)。
ディートリッヒエップ2010

3
@Dietrich Epp:それは完全に真実ではありません。x86-64にはISAで認識できるレジスタがさらにありますが、最近のx86実装には通常、実行を高速化するためにISAのレジスタにマップされるRISCスタイルのレジスタファイルがあります。
Billy ONeal、2010

「nVidiaから、Intelの過ちの1つがバイナリ形式をハードウェアの近くに置いたままにしていたことを聞いたことがあります。」-これとCUDAのPTXパーツは入手できませんでした。

1
@Dietrech Epp:「そして、ほとんどのx86チップの命令は、キャッシュされる前ではなく、キャッシュされる前にデコードされます」それは正しくありません。それらはデコードされる前にキャッシュされます。Pentium 4には、デコード後にキャッシュされる追加のトレースキャッシュがあったと思いますが、それは廃止されました。
Nathan Fellman、2010

それは真実ではありません。最新の「サンディブリッジ」プロセッサは一種のトレースキャッシュを使用しているため(ペンティアム4の場合のように、あの古い男の子:D)、テクノロジが消えて戻ってきます...
Quonux

3

人々がすでに言及した理由に加えて:

  • x86-16には、奇妙なメモリアドレッシングスキームがあり、単一のメモリロケーションを最大4096の異なる方法でアドレス指定でき、RAMを1 MBに制限し、プログラマーに2つの異なるサイズのポインターを処理することを強制しました。幸い、32ビットへの移行により、この機能は不要になりましたが、x86チップには依然としてセグメントレジスタの残骸が残っています。
  • x86の故障していないがそれ自体の混乱を私たちに残して、(MS-DOSは、任意のコンパイラが付属していませんでしたので、主に)MIPSだったように、x86の呼び出し規約は、標準化されていなかった__cdecl__stdcall__fastcallなど、

うーん.. x86の競合他社について考えるとき、私はMIPSについては思いません。ARMまたはPowerPCたぶん....
Billy ONeal

@Billy:x86は永遠に存在しています。かつてMIPSはx86の競争相手でした。私が覚えているように、x86はMIPSと競合するレベルに到達するために、その作業を切り詰められました。(MIPSとSPARCがワークステーションの領域で戦っていた頃)
Shannon Severance 2010年

@Shannon Severance:かつて何かがあったからといって、それが何かを意味するわけではありません。
Billy ONeal

2
@supercat:フラットx86-32メモリモデルの時代の人々が忘れがちなのは、16ビットは64kのメモリを意味するということです(数学をやっている人なら誰でも、魔法は不可能であり、8086はそうではなかったことを理解するでしょう)疑いを持たないプログラマのための厄介な罰)。64kを回避する方法はいくつかありますが、8086ソリューションは適切な妥協案でした。
Olof Forshell 2013年

2
@OlofForshell:8086は68000(16MBの線形アドレス空間と4ギグへの明確なパスがあった)ほど良くなかったという事実を多くの人が嘆いたと思います。確かに32ビットプロセッサに移行すると、64K以上にアクセスしやすくなりますが、8086は16ビットアーキテクチャであり、8ビット8080からステップアップするように設計されています。インテルが飛躍する必要がある理由はわかりません8ビットから32ビットに直接。
スーパーキャット2013年

3

x86をターゲットとするコンパイラーを作成しようとした場合、またはx86マシンエミュレーターを作成した場合、あるいはISAをハードウェア設計に実装しようとした場合でも、答えの一部に到達すると思います。

「x86は醜い!」引数、私はまだMIPSよりもx86アセンブリを書くのが楽しいと思います(たとえば)-後者は単純に退屈です。これは常に、人間よりもコンパイラに優しいことを意味していました。試してみれば、コンパイラの作成者にとってチップがより敵意があるとは思いません...

私にとって最も醜い部分は、(リアルモード)セグメンテーションが機能する方法です-物理アドレスには4096のsegment:offsetエイリアスがあります。最後にそれが必要になったのはいつですか?セグメント部分が厳密に32ビットアドレスの上位ビットである場合、状況は非常に単純になります。


m68kはよりおもしろく、x86(多くのm68kプログラマーにとっては「人間的」とは思えない)よりもはるかに人間に優しいものですが、適切なPoVが人間がそれらのアセンブリでコードを記述できる方法である場合。
ShinTakezou

セグメント:オフセットアドレッシングは、CP / M-ワールドとある程度互換性を保つための試みでした。これまでで最悪の決定の1つ。
チューリング完了

@Turing Complete:segment:offsetは、主にCP / Mの世界との互換性を保つための試みではありませんでした。コード、データ、スタック、その他のメモリ領域を異なるセグメントに配置することにより、16ビットプロセッサが64 KBを超えるアドレスを指定できるようにしたことは、非常に成功した試みでした。
Olof Forshell、2011年

1
実際には、データとスタックを異なるセグメントに配置することは、Cにとってまったく役に立たなかった。asmでしか使えませんでした。Cでは、ポインターは静的、自動、また​​は動的に割り当てられたストレージ期間を持つデータを指すことができるため、セグメントを除外する方法はありません。PascalやFortranなどで有用だったかもしれませんが、当時はすでに支配的な言語であったCには役に立ちませんでした...
R .. GitHub STOP HELPING ICE

2
@Bernd:fs / gsがスレッドローカルストレージに選択された理由は、セグメントレジスタがこれに適しているということではありません。これは、x86のレジスターが大幅に不足していて、セグメントレジスターが未使用だったというだけのことです。スレッド構造を指す汎用レジスターも同様に機能し、実際には、より多くのレジスターを持つ多くのRISCシステムが1つをスレッドポインターとして使用します。
R .. GitHub ICEのサポートを停止

1
  1. x86には、非常に限定された汎用レジスタのセットがあります。

  2. 効率的なロード/ストア方法ではなく、最下位レベル(CISC hell)で非常に非効率的な開発スタイルを促進します。

  3. インテルは明らかに愚かなセグメント/オフセットを導入するという恐ろしい決定を下しました-(現時点ではすでに)旧式のテクノロジーとの互換性を維持するためのメモリアドレス指定モデル

  4. 誰もが32ビットに移行していたときに、x86はわずか16ビット(主に-8088-8ビットの外部データパスしかなく、さらに恐ろしい!)


私(および私は、あらゆる世代のPCを開発者の観点から見てきたDOSのベテランです!)ポイント3.が最悪でした。

90年代前半に発生した次の状況を想像してください(主流!):

a)レガシーの理由で非常識な制限があったオペレーティングシステム(640kBの簡単にアクセスできるRAM)-DOS

b)オペレーティングシステムの拡張機能(Windows)で、RAMの面でより多くのことを実行できますが、ゲームなどに関して制限されていて、地球上で最も安定したものではありませんでした(幸い、これは後で変更されましたが、私はここでは90年代前半について話している)

c)ほとんどのソフトウェアはまだDOSであり、特別なソフトウェア用にブートディスクを作成する必要がありました。これは、EMM386.exeが好きなプログラムもあれば、嫌いだったプログラムもあるためです(特にゲーマー-そして私は現時点ではAVIDゲーマーでした-知っていることここで話しています)

d)MCGA 320x200x8ビットに制限されていました(OK、特別なトリックでもう少しありましたが、360x480x8が可能でしたが、ランタイムライブラリのサポートなしでしかできませんでした)。

e)しかし、ハードウェアに関しては、かなりのメガバイトのRAMを備えた32ビットマシンと、最大1024x768をサポートするVGAカードがありました。

この悪い状況の理由は?

インテルによる簡単な設計決定。マシンインストラクションレベル(バイナリレベルではない!)との互換性はすでに死んでいたものだと思います。8085だったと思います。他の、一見無関係な問題(グラフィックモードなど)は、技術的な理由と非常に狭いために関連していましたx86プラットフォーム自体がもたらしたマインドアーキテクチャ。

今日、状況は異なりますが、アセンブラーの開発者またはx86のコンパイラバックエンドを構築する人に聞いてください。非常に少ない数の汎用レジスターは、恐ろしいパフォーマンスキラーに過ぎません。


8086セグメントアーキテクチャの主な問題は、専用セグメントレジスタ(ES)が1つしかなかったことと、プログラミング言語がそれと効果的に連携するように設計されていないことです。それが使用するスケーリングされたアドレス指定のスタイルは、オブジェクトが任意のアドレスで開始できることを期待しないオブジェクト指向言語で非常にうまく機能します(1つが段落の境界にオブジェクトを配置する場合、オブジェクト参照は2バイトではなく2バイトで十分です)四)。1は、PCコードに早期のMacintoshコードとを比較した場合、8086は実際には68000に比べてかなり良いに見える
supercat

@supercat:実際には、esレジスタは何か、つまり保存(movs、stos)またはスキャン(cmpsおよびscas)を必要とする文字列命令に専用のWASです。すべてのセグメントレジスタからの64KiBアドレス指定により、コード、データ、スタックメモリ(cs、ds、ss)以外のメモリへの「ミッシングリンク」も提供されました。セグメントレジスタは、レジスタの64Kibメモリブロックの外部をアドレス指定できないという点で、一種のメモリ保護スキームを提供しました。x86が16ビットアーキテクチャであり、当時のリソグラフィの制約がある場合、どのようなソリューションを提案しますか?
Olof Forshell 2016

@OlofForshell:ESは文字列命令に使用されましたが、それらを使用しないコードの非コミットレジスタとして使用できました。過度のオペコードスペースを必要とせずにseg-regのボトルネックを緩和する方法は、次のr / m形式の命令に対して "r"フィールドがCS / SS / DSから選択することを指定する "rseg"プレフィックスを付けることです。 / ES / FS / GS / ?? / ?? AX / BX / CX / DX / SI / DI / SP / BPの代わりに、FS / GSの接頭辞と、LFSとLGS(LDSやLESなど)の指示を追加します。8086のマイクロアーキテクチャがどのようにレイアウトされているかはわかりませんが、そのようなものがうまく機能したと思います。
スーパーキャット2016

@supercat:私が書いたように、「レジスタesは...以外のメモリへのミッシングリンクも提供します」Fsとgsは386まで覚えていませんでした。
Olof Forshell、2016

1
@OlofForshell:そうではなかったため、ほとんどの点で80286アーキテクチャは8086アーキテクチャよりもさらに悪いものになりました。私のポイントは、セグメントレジスタをさらに2つ(またはさらに言えば1つ)追加すると、8086アーキテクチャがはるかに便利になり、セグメントレジスタが次のようにアクセスできれば、命令セットがよりクリーンで便利になるということです。他のもの。
スーパーキャット2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.