標準化委員会が注目するエキゾチックなアーキテクチャ


154

CおよびC ++標準では、言語の実装の多くの側面が定義されたままであることを知っています。それは、他の特性を持つアーキテクチャがある場合、その標準に準拠するコンパイラを作成することが非常に困難または不可能だからです。

40年前は、どのコンピュータにも独自の仕様があったことを知っています。ただし、今日使用されているアーキテクチャについては知りません。

  • CHAR_BIT != 8
  • signed は2の補数ではありません(Javaでこれに問題があったと聞きました)。
  • 浮動小数点はIEEE 754に準拠していません(編集:「IEEE 754バイナリエンコーディングではない」という意味です)。

私が尋ねている理由は、C ++が固定サイズの型などの他の低レベルの側面を義務付けないのは良いことだと人々によく説明するためです。「他の言語」とは異なり、正しく使用するとコードが移植可能になるので良いです(編集:符号+大きさのアーキテクチャでの2の補数演算など、マシンの低レベルの側面のエミュレーションを必要とせずに、より多くのアーキテクチャに移植できるため) 。しかし、私は自分が特定のアーキテクチャを指すことができないのは残念です。

だから問題は:どのアーキテクチャが上記の特性を示すのか?

uint*_tはオプションです。


9
あなたはそれを逆に持っていると思います。たとえば、C ++が符号付き整数の2の補数を義務付けている場合、C ++コードはより移植性が高くなります。なぜC ++標準委員会がこれを義務付けないのかという問題は別の問題です。特に、あなたが言っていることにもかかわらず、非標準アーキテクチャ用のコンパイラを書くことは不可能ではないので、プラットフォームが直接サポートしていない場合でも、常に8ビット文字または2の補数演算をシミュレートできます。
ジョン

8
@john:それは非現実的であるため、非標準の適合コンパイラは適合コードよりも高速なコードを生成します。そして、それによってコードがよりポータブルになる方法はまだわかりません。
Yakov Galka 2011

4
標準がそうである本当の理由は、それがいくつかの理想的な解決策であるからではないと確信しています。しかし、標準が作成されたとき、多くのCおよびC ++コンパイラがすでに存在し、標準委員会が既存のコンパイラを拒否したくなかったためです。
ジョン08

4
@john:C ++標準を作成するときは、「コンパイラの作成者にとって簡単にする」ことが優先事項であるとは思いません(C ++は、解析が最も難しい言語の1つであり、この言語は、コンパイラの作成者にとっても簡単ではありません)。ただし、パフォーマンス、幅広いプラットフォームのサポート、下位互換性は非常に重要です。そして、あなたが言及する制限が規格に追加されると、これら3つすべてが影響を受けます。
Sander De Dycker、2011

5
コンパイラではなくハードウェアについてです。C ++では、ハードウェア機能を直接使用できるようにするために、いくつかを未指定のままにしています。いずれにしても、電話アプリはメインフレームで実行されないため、コードが準拠していても移植性はありません。
Bo Persson、2011

回答:


114

これを見てください

Unisys ClearPath Doradoサーバー

まだすべてのUnivacソフトウェアを移行していないユーザーに下位互換性を提供します。

キーポイント:

  • 36ビットワード
  • CHAR_BIT == 9
  • 補数
  • 72ビットの非IEEE浮動小数点
  • コードとデータ用の個別のアドレス空間
  • ワードアドレス
  • 専用スタックポインタなし

ただし、C ++コンパイラを提供しているかどうかはわかりませんが、可能です。


そして今、彼らのCマニュアルの最新版へのリンクが浮上しました:

Unisys Cコンパイラプログラミングリファレンスマニュアル

セクション4.5には、9、18、36、および72ビットのデータ型の表があります。

USC Cコンパイラでのデータ型のサイズと範囲


13
そのアーキテクチャーでvoid *を使用するには地獄が必要だと思います。
luiscubal 2011

13
@ybungalobill -私は信じているchar*void*、同じサイズ、およびその他のポインタを保持するのに十分な大きさでなければなりません。残りは実装次第です。
Bo Persson

22
@ybungalobill:古いWin16コンパイラでは、通常のポインタはポインタの近くにあり、16ビットのオフセットしか含まれていなかったためsizeof(int*) == 2、farポインタにも16ビットのセレクタがありましたsizeof(void*) == 4
Adam Rosenfield、2011

10
C ++コンパイラのオンラインマニュアルがあります。また、これはUnisysメインフレームアーキテクチャの1つにすぎないことも指摘しておく必要があります。もう1つは、48ビットの符号付きマグニチュードタグ付きアーキテクチャです(C ++のものではなく、Cマニュアルしかありません)。残りに関して:私はsizeof(int*) != sizeof(char*)ここではそうは思わない:両方とも36ビットです。ただし、のバイトセレクタはchar*上位ビットにあり、では無視されint*ます。(ただし、 `sizeof(char *)> sizeof(int *)である他のマシンを使用しました。)
James Kanze

16
@Adam Rosenfield MS / DOS 16ビットコンパイラでは、異なる "モード"があり、データポインタは関数ポインタと同じサイズであるとは限りませんでした。しかし、少なくとも私が使用したものでは、すべてのデータポインタ(を含むvoid*)は常に同じサイズでした。(もちろん、あなたがに関数ポインタを変換することができなかったvoid*ため、void*いずれか、小さいかもしれませんが、標準によると、今日はそれを行うことはできません。)
ジェームズ・観世

51

メインフレームに当てはまる想定はありません。手始めに、IEEE 754を使用するメインフレームについては知りません。IBMはベース16浮動小数点を使用し、両方のUnisysメインフレームはベース8を使用します。Unisysマシンは他の多くの点で少し特殊です。Boは2200について言及していますアーキテクチャですが、MPSアーキテクチャはさらに奇妙です。48ビットのタグ付きワードです。(単語がポインターであるかどうかは、単語内のビットに依存します。)そして、数値表現は、浮動小数点と整数演算の間に実際の違いがないように設計されています。浮動小数点は8を基数とします。それは正規化を必要としません、そして私が見た他のすべての浮動小数点とは異なり、それは小数を左ではなく仮数の右に置き、指数に符号付きの大きさを使用します(仮数に加えて)。整数の浮動小数点値が符号付きの大きさの整数とまったく同じビット表現を持っている(または持つことができる)という結果。また、浮動小数点演算命令はありません。2つの値の指数が両方とも0の場合、命令は整数演算を行い、それ以外の場合、浮動小数点演算を行います。(アーキテクチャにおけるタグ付けの哲学の継続。)つまり、int 48ビットを占有する場合があり、そのうちの8ビットは0でなければなりません。そうでない場合、値は整数として扱われません。


4
IBMメインフレーム(z / Architecture)は、IEE754浮動小数点をサポートしています。
Nikita Nemkin 16年


6
@Nikita-彼らはやります。当初は、Javaをサポートするための(高価な)アドオンでした。
Bo Persson 2017年


42

IEEE 754に完全に準拠することは、浮動小数点実装ではまれです。その点で仕様を弱めると、多くの最適化が可能になります。

たとえば、サブノルムサポートはx87とSSEで異なります。

乗算と加算の融合のような最適化は、ソースコードで個別でしたが、結果もわずかに変更しますが、一部のアーキテクチャでは優れた最適化です。

または、x86では、IEEEに厳密に準拠するために、特定のフラグを設定するか、浮動小数点レジスタと通常のメモリの間で追加の転送を行って、内部の80ビット浮動小数点数ではなく、指定された浮動小数点タイプを強制的に使用する必要があります。

また、一部のプラットフォームではハードウェアフロートがまったくないため、ソフトウェアでそれらをエミュレートする必要があります。また、IEEE 754の要件の一部は、ソフトウェアでの実装にコストがかかる場合があります。特に、丸め規則が問題になる場合があります。

私の結論は、IEEEへの厳密な準拠を常に保証する必要がないという状況に陥るために、エキゾチックなアーキテクチャを必要としないということです。このため、厳密なIEEE準拠を保証するプログラミング言語はほとんどありませんでした。


7
もう1つの「エキゾチック」なハードウェアセットは、IBMのメインフレームであり、浮動小数点形式はIEEE標準よりも古いものです。Javaとは異なり、C ++は引き続き既存のハードウェアを使用できます。
Bo Persson、2011

5
IEEE 754はGPUで完全にはサポートされていません。
kerem 2011

3
IEEE 754への厳密な準拠の欠如は一部の人にとって悩みの種ですが、OPが本当に気にかける問題の範囲内にあるとは私は思いません。
全面的に

3
@Matthieuこれも「C」のタグが付いているので、Cコンパイラの気まぐれでメモリに流された80ビット浮動小数点レジスタで浮動小数点プログラムが取る可能性のあるすべての値を伝えることができるCアナライザについて言及する必要があります。blog.frama-c.com/index.php?post/2011/03/03/cosine-for-real
Pascal Cuoq

2
@MatthieuM .:残念すぎるISO / ANSIは、可変個引数パラメーターが浮動小数点と整数の引数の最小/最大サイズを指定することを許可していませんでした。もしそうなら、80ビットlong doubleは、1つの本当の問題がそれがでうまく機能しないということだったので、有用で長持ちするタイプだったかもしれませんprintf。拡張doubleが先行1を格納するという事実は、非FPUシステムでの計算を明示的に高速化し、他の型との変換以外のコンテキストでの非正規化の特別な処理の必要性を排除します。悪いCがprintfすべてを台無しにした。
スーパーキャット2015

40

私が見つかりました。このリンクは、いくつかのシステムをリスト場所CHAR_BIT != 8。彼らは含まれています

一部のTI DSPは CHAR_BIT == 16

BlueCore-5チップ(ケンブリッジシリコンラジオのBluetoothチップ) CHAR_BIT == 16

そしてもちろん、スタックオーバーフローに関する質問があります。 ますどのプラットフォームに8ビット文字以外の何かがあります

2の補数以外のシステムについては、 comp.lang.c ++。moderatedに関する興味深い記事があります。要約:1の補数または符号と大きさの表現を持つプラットフォームがあります。


5
Analog Devices 32ビットSHARC DSPにはCHAR_BIT=32TMS32F28xxのTexas Instruments DSPが搭載されていCHAR_BIT=16ます。GCC 3.2 for PDP-10にはがありCHAR_BIT=9ます。S / 360も8ビットではない文字を持っているかもしれません。
osgx

1
私はまだ「2の補数でない」アーキテクチャの例を望んでいます。特にそれがCHAR_BITS部分的な複製であることが起こったので。
Yakov Galka 2011

TIのDSPに16ビット文字が含まれているのは、実装者がそれを選択したからです(正しく機能させるには少し手間がかかりますが、不合理に難しいIIRCではありません。おそらく、基になるコンパイラのcodegenの足場にいくつかの「穴」があるだけです)。 。だからそれはいくつかの深い建築上の理由ではありません。Cコードは抽象的なマシンで動作します。16ビットINTしかなければ、それぞれに2つの文字を格納し、(少なくとも)ピープホールオプティマイザに読み取り-変更-書き込みのマージを追加します。確かに、それはより多くの仕事ですが、彼らがこれまで現れない場所でこのような奇妙なタイプに対処するために誰もがどれだけ多くの仕事をするかを見てください。ああ。
モニカを

24

VAXシステムがまだ使用されていると私はかなり確信しています。IEEE浮動小数点をサポートしていません。彼らは独自のフォーマットを使用しています。AlphaはVAXとIEEEの両方の浮動小数点形式をサポートしています。

新しいCrayシステムはIEEEを使用していますが、T90のようなCrayベクトルマシンにも独自の浮動小数点形式があります。(私が使用したT90は数年前に廃止されました。まだアクティブに使用されているものがあるかどうかはわかりません。)

T90には、ポインターと整数の興味深い表現もいくつかありました。ネイティブアドレスは64ビットワードのみを指すことができます。CおよびC ++コンパイラーはCHAR_BIT == 8(UnixのフレーバーであるUnicosを実行し、他のシステムと相互運用する必要があったために必要)を備えていましたが、ネイティブアドレスは64ビットワードしかポイントできませんでした。すべてのバイトレベルの操作はコンパイラによって合成され、void*またはchar*ワードの上位3ビットにバイトオフセットを記憶されています。そして、私はいくつかの整数型にパディングビットがあったと思います。

IBMメインフレームは別の例です。

一方、これらの特定のシステムは必ずしも言語標準の変更を排除する必要はありません。Crayは、CコンパイラをC99にアップグレードすることに特に関心を示していませんでした。おそらくC ++コンパイラにも同じことが当てはまります。可能性があり、このような符号付き整数のビットをパディングすることなくCHAR_BIT == 8、IEEE形式の浮動小数点でない場合、完全なセマンティクス、及び2の補数を必要としてホスト実装のための要件を厳しくすることは合理的です。古いシステムは以前の言語標準をサポートし続けることができ(C99が出たときにC90は死にませんでした)、DSPなどの自立型実装(組み込みシステム)の要件は緩和される可能性があります。

一方で、将来のシステムが今日ではエキゾチックと見なされることを行うには、十分な理由があるかもしれません。


6
過度に厳しい基準がイノベーションをどのように妨げるかについての最後の良い点。三値状態の量子(または有機)コンピュータを入手する場合、unsigned整数型のモジュロ演算要件は大きな問題になりますが、符号付き演算は問題ありません。
Ben Voigt 2013

@BenVoigtなぜその符号なし算術が苦痛なのですか?それらのコンピューターでは3 ^ nを法とする加算器は不可能ではありませんか?
phuclv 2015

2
@LưuVĩnhPhúc:ハードウェア演算が3 ** nを法として実行され、2 ** nを法として演算が定義されるC ++符号なし型を提供することはまさにその点です。
Ben Voigt 2015

2
独自のアーキテクチャを備えた特殊な組み込みシステムをターゲットとするクロスコンパイラのホストとして、現在も1つのVAX 11/780が使用されていることを知っています。その特定のVAXを維持するために、カストディアンは予備品を求めて博物館に接近しています。
Peter

2
@キース-技術的には、ターゲットの組み込みシステムは非常に重要であるため、唯一の障害は規制要件を満たす証拠を提供するプロセスを通過することです。非技術的な障害(組織の政治など)はたくさんありますが、今日まで克服することはできませんでした。現在、ホストを更新するよりも博物館を襲撃するためにケースをマウントする方が簡単です。
ピーター

16

CHAR_BITS

gccソースコードによると:

CHAR_BITである16ためのビット1750Adsp16xxのアーキテクチャ。
CHAR_BITである24ためのビットDSP56kののアーキテクチャ。
CHAR_BITである32ためのビットc4xアーキテクチャ。

次のようにして、簡単に詳細を見つけることができます。

find $GCC_SOURCE_TREE -type f | xargs grep "#define CHAR_TYPE_SIZE"

または

find $GCC_SOURCE_TREE -type f | xargs grep "#define BITS_PER_UNIT"

CHAR_TYPE_SIZEが適切に定義されている場合。

IEEE 754準拠

ターゲットアーキテクチャが浮動小数点命令をサポートしていない場合、gccはソフトウェアのフォールバックを生成する可能性があります。デフォルトでは標準に準拠していません。それ以上に、特別なオプション(-funsafe-math-optimizations魔女もゼロの符号保存を無効にするなど)を使用できます。


3
人気のあるコンパイラのソースを見るようにOPに指示するだけで賛成です。これはこの場合のRFTMの定義であるため、人々が最初に見るべき場所です。
underscore_d

9

IEEE 754バイナリ表現は、最近までGPUでは一般的ではありませんでした。GPU 浮動小数点パラノイアを参照してください。

編集:GPU浮動小数点がグラフィックスとは関係なく、通常のコンピュータープログラミングに関連しているかどうかの質問がコメントで発生しました。もちろん!今日、工業的に計算されている最も高性能なものはGPUで実行されます。リストには、AI、データマイニング、ニューラルネットワーク、物理シミュレーション、天気予報などが含まれます。コメントのリンクの1つは、理由を示しています。GPUの桁違いの浮動小数点の利点。

私が付け加えたいもう1つのことは、OPの質問により関連しています。GPU浮動小数点がIEEEでなく、GPUをプログラムするための今日のOpenCLやCUDAなどのAPIがないときに、10〜15年前に人々は何をしましたか?信じられないかもしれませんが、初期のGPUコンピューティングのパイオニアは、APIなしでGPUプログラミングすることができました。私は会社でそれらの1人に会いました。彼がやったことは次のとおりです。彼は、計算に必要なデータを、作業中の値を表すピクセルを含む画像としてエンコードし、OpenGLを使用して必要な操作を実行しました(「ガウスぼかし」など)。など)、結果の画像をデコードして結果の配列に戻します。そして、これはまだCPUを使用するよりも高速でした!

そのようなことが、NVidiaに最終的に内部データバイナリをIEEEと互換性を持たせ、画像操作ではなく計算指向のAPIを導入するきっかけとなりました。


GPUはどのように関連していますか?(a)このページは非常に古くなっているようです。(b)今日まで、CでGPUをプログラミングすることはできません。Cは、私の知る限り、GPUがサポートしていない再帰関数などをサポートしているためです。したがって、必要に応じてコンパイラを作成することもできません。
Yakov Galka 2016年

1
@ybungalobill、反復的な作業のGPUへのオフロードは現在 大規模な計算に推奨される方法です。実際、私は現在C ++で開発しています。さいわい、IEEE 754互換の浮動小数点のバイナリ表現を持つNVidia CUDA GPUでのみ機能します。
マイケル

GPUがGP計算に使用されていないとは言えません。構文の類似性にもかかわらず、カーネルをCで実際にプログラムしないと言いました。int f(int n) { return n <= 1 ? 1 : n * f(n-1); }CUDAで実行できますか?いいえの場合、GPUはこの質問には関係ありません(CおよびC ++委員会について尋ねます)。
Yakov Galka 2016年

6
@ybungalobill:そのいくつかの答え。まず、CUDAはC、C ++、およびFortranをサポートしています。一般的な8スレッドCPUに対する2048スレッドGPUの大きなパフォーマンスの利点については、同じリンクを参照してください。2番目に、CUDA 5.0までのCUDAプログラミングモデルの再帰(「動的並列処理」と呼ばれます)のサポートの欠如を含め、これらの言語のサブセット(大きいものでも)のみがサポートされています。3番目に、再帰は通常ループに置き換えることができますが、これはとにかくマルチスレッドのパフォーマンスに必要です。
マイケル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.