33

私はARMのプログラミングにかなり慣れていません。ARMv4、ARMv5、ARMv6などのアーキテクチャがいくつかあることに気づきました。これらの違いは何ですか?それらは異なる命令セットまたは動作を持っていますか?

最も重要なことは、ARMv6用にCコードをコンパイルした場合、ARMv5で実行できるのでしょうか。ARMv6で実行されているARMv5コードはどうですか?それとも、カーネルアセンブリコードを書いている場合にのみ、違いを心配する必要がありますか?

4

5 に答える 5

40

ARMの世界は少し厄介です。

Cプログラマーにとって、物事は単純です。すべてのARMアーキテクチャーは、フラットなアドレス指定プログラミングモデルを備えた通常の32ビットを提供します。Cソースコードを使用している限り、エンディアンとパフォーマンスだけが異なります。ほとんどのARMプロセッサ(古いモデルでも)は、ビッグエンディアンとリトルエンディアンの両方にすることができます。次に、ロジックボードとオペレーティングシステムによって選択が行われます。優れたCコードはエンディアンニュートラルです:プラットフォームのエンディアンに関係なく、正しくコンパイルおよび動作します(エンディアンニュートラルは信頼性と保守性だけでなく、パフォーマンスにも優れています:非ニュートラルコードは、異なるサイズのポインターを介して同じデータにアクセスするコードです、これは、コンパイラがコードを最適化するために使用する厳密なエイリアスルールに大混乱をもたらします)。

バイナリ互換性(つまり、一度コンパイルされたコードを再利用する)を考慮すると、状況はまったく異なります。


  • いくつかの命令セットがあります。
    1. 26ビットのプログラムカウンターを備えた元のARM命令セット(非常に古く、今日では遭遇する可能性は非常に低い)
    2. 32ビットプログラムカウンターを備えたARM命令セット(「ARMコード」と呼ばれることもあります)
    3. Thumb命令セット(16ビットの簡略化されたオペコード)
    4. Thumb-2命令セット(拡張機能付きのThumb)

特定のプロセッサは、いくつかの命令セットを実装する場合があります。ARMコードのみを知っている最新のプロセッサはStrongARMです。これは、すでにかなり古い(15年)ARMv4の代表です。ARM7TDMI(ARMv4Tアーキテクチャ)は、Cortex-Mを除く後続のほとんどすべてのARMシステムと同様に、ARMとThumbの両方を認識しています。規則が変更される場所に適切な接着剤が挿入されている限り、ARMコードとThumbコードを同じアプリケーション内で混在させることができます。これはサムインターワーキングと呼ばれ、Cコンパイラによって自動的に処理できます。

Cortex-M0はThumb命令のみを知っています。「通常の」ARMプロセッサでは、オペレーティングシステムは(割り込みを処理するために)ARMコードを使用する必要があるため、いくつかの拡張機能を認識しています。したがって、Cortex-M0はいくつかのThumb-for-OSのことを知っています。これは、アプリケーションコードには関係ありません。

他のCortex-MはThumb-2しか知りません。Thumb-2は、少なくともアセンブリレベルでは、Thumbとほとんど下位互換性があります。


  • 一部のアーキテクチャでは、追加の命令が追加されます。

したがって、これがARMv6用であることを示すコンパイラスイッチを使用してコードをコンパイルした場合、コンパイラはARMv5ではなくARMv6で数少ない命令の1つを使用できます。これは一般的な状況であり、ほとんどすべてのプラットフォームで発生します。たとえば、-march=core2フラグを使用してGCCを使用してPCでCコードをコンパイルすると、結果のバイナリが古いPentiumプロセッサで実行できない場合があります。


  • いくつかの呼び出し規則があります。

呼び出し規約は、関数がパラメーターと戻り値を交換する方法を指定する一連のルールです。プロセッサはそのレジスタのみを認識しており、スタックの概念はありません。呼び出し規約は、パラメーターがどのレジスターに入るのか、そしてそれらがどのようにエンコードされるのかを示します(たとえば、charパラメーターがある場合、それはレジスターの下位8ビットに入りますが、呼び出し元は上位24ビットをクリア/符号拡張することになっています。か否か ?)。スタックの構造と配置について説明します。構造体フィールドの配置条件とパディングを正規化します。

ARMには、ATPCS(古い)とAAPCS(新しい)という2つの主要な規則があります。これらは、浮動小数点値に関してはまったく異なります。整数パラメーターの場合、それらはほとんど同じです(ただし、AAPCSではより厳密なスタックアライメントが必要です)。もちろん、規則は命令セットとThumbインターワーキングの存在によって異なります。

場合によっては、ATPCSとAAPCSの両方に準拠するバイナリコードが存在する可能性がありますが、それは信頼性が低く、不一致に関する警告はありません。つまり、重要なのは、異なる呼び出し規則を使用するシステム間で真のバイナリ互換性を実現することはできないということです。


  • オプションのコプロセッサーがあります。

ARMアーキテクチャは、コア命令セットに独自の命令を追加するオプションの要素で拡張できます。FPUはそのようなオプションのコプロセッサーです(実際にはめったに発生しません)。もう1つのコプロセッサーはNEONです。これは、一部の新しいARMプロセッサーに搭載されているSIMD命令セットです。

コプロセッサーを使用するコードは、オペレーティングシステムが対応するオペコードをトラップし、ソフトウェアでコプロセッサーをエミュレートしない限り、そのコプロセッサーを備えていないプロセッサーでは実行されません(これは、ATPCS呼び出しを使用するときに浮動小数点引数で発生することです。慣例、そしてそれは遅いです)。


要約すると、Cコードがある場合は、それを再コンパイルします。別のアーキテクチャまたはシステム用にコンパイルされたコードを再利用しようとしないでください。

于 2010-12-08T18:45:51.030 に答える
5

このARM対ARMのことを、wintelコンピュータ対intelmacのように考えてください。両方のコンピューターに同じインテルチップ(ファミリー)があるとしても、Cコードの一部を一度にコンパイルして、両方のプロセッサーで問題なく実行できると仮定します。プログラムがどこで、なぜ変わるのかは、Intelプロセッサとは何の関係もありませんが、その周りのチップとマザーボード、そしてこの場合はオペレーティングシステムと関係があります。

ARMとARMの違いのほとんどはコアではなく、コアを取り巻くベンダー固有のロジックです。したがって、これは質問の誤謬です。Cコードが標準のAPI呼び出しを呼び出すアプリケーションである場合は、arm、intel、powerpcなどでコンパイルする必要があります。アプリケーションがオンチップまたはオンボード周辺機器と通信するようになると、プロセッサの種類に関係なく、1つのボード、1つのチップが異なり、その結果、そのチップまたはマザーボード用にCコードを記述する必要があります。ARMv6のバイナリをコンパイルすると、ARMv4で未定義と見なされる命令が発生する可能性があり、実行される可能性があります。ARMv4用にコンパイルする場合、ARMv6はそれを問題なく実行するはずです。

せいぜい、このアプリケーションスペースにいる場合は、パフォーマンスの違いだけが表示される可能性があります。そのうちのいくつかは、コンパイラオプションの選択に関係しています。そして時々あなたはあなたのコードを手伝うことができます。可能な限り、除算と浮動小数点を避けることをお勧めします。私は掛け算が好きではありませんが、プッシュされた場合、割り算の代わりに掛け算を取ります。x86は、アラインされていないアクセスで甘やかされてしまいました。アラインされたI / Oから始めれば、アラインされたアクセスを好む他のチップに入るとき、またはさまざまなオペレーティングシステムやブートローダーは、ARMが反応するように構成しますが、x86で慣れているものはありません。同様に、この習慣を維持すれば、x86コードははるかに高速に実行されます。

ARM ARMのコピーを入手してください(google:ARM Architectural Reference Manual、無料でダウンロードできます。現在のリビジョンが何であるか、リビジョンIか何かがわかりません)。ARM命令セットを参照して、ほとんどの命令がすべてのコアでサポートされていることを確認してください。また、divideやbyteswapなどの一部が時間の経過とともに追加されていることを確認してください。コア間に恐れるものは何もないことがわかります。

システムの観点から考えると、wintelとintelmacです。ARMはチップを製造せ​​ず、コアを製造してライセンスを供与します。チップにARMを使用しているほとんどのベンダーは、その周りに独自の特別なソースを持っています。つまり、同じプロセッサを中央に配置したwintelとMacのようなものですが、プロセッサが接触して使用する必要のあるすべてのものに関しては、まったく異なります。ARMコアだけでなく、ARMは周辺機器、浮動小数点ユニット、キャッシュなどを販売しています。たとえば、同じARMv4があったとしてもごくわずかです。コードが違いに触れている場合、そうでない場合は問題が発生します。

ARM ARMに加えて、チップのアーム部分にはTRM(テクニカルリファレンスマニュアル)があります。ただし、使用しているコンポーネントに対して間違ったtrmを取得すると、頭痛の種になる可能性があります。TRMには、レジスタの説明など、ARM ARMにはないものが含まれている場合がありますが、アプリケーションスペースに住んでいる場合は、それらのいずれも、ARMARMも必要ない可能性があります。ARM ARMは、他に何もないとしても、教育目的に適しています。アラインされていないアクセスを分割または使用したくない理由を理解する。

于 2010-12-08T05:44:05.743 に答える
4

ARM自体は、ユーザーコードに固執することを条件に、かなり互換性があります(もちろんカーネルコードは異なります)。ホストされたOS環境では、ARMv5(ARM926プロセッサ)に固執する可能性があります。

大きな違いは次のとおりです。

  1. キャッシュの動作は大きく異なります。一部のARMのキャッシュは仮想的にアドレス指定されているため、プロセスの切り替えが困難になる可能性があります。
  2. FPUにはいくつかのフレーバーがあります(VFP、NEONなど)。多くの小さなプロセッサにはFPUさえありません。
  3. サムモードが大幅に変更されました。ARMv5間のThumbモードは、Thumb2(ARMv6 +)に移植できず、下位互換性もありません。
于 2010-12-07T20:17:14.793 に答える
3

違いが本当に重要な場合は、ARMの公開ドキュメントからその違いを理解できるはずです。

しかし、高級言語で書くことの全体的なポイントは(たとえそれがCのように「高い」だけであっても)、それについて心配しないことです。再コンパイルするだけです。カーネル内でさえ、実際にはそれほど多くをアセンブリで記述する必要はありません。また、アセンブリで何かを作成する必要がある場合(つまり、最大のパフォーマンスを得るためだけでなく)、通常はCPUの選択だけではありません(たとえば、どこに直接メモリマップされているのか)。

于 2010-12-08T00:09:14.193 に答える
3

一般にアーキテクチャ間で移植するときにチェックする領域の非常に迅速で汚いリスト:

  • エンディアン:ユニオンの使用、データ型のキャスト、ビットフィールド、データ共有
  • アラインメント:アラインメント要件だけでなく、アラインメントされていない可能性のあるアクセスのパフォーマンス特性
  • メモリモデル:弱いvs強い?
  • マルチコア:コヒーレンシはどのように機能しますか?
  • その他:符号付きデータ型と符号なしデータ型、データ構造のパッキング、スタックの使用法、列挙型データ型...
于 2014-03-16T07:12:02.957 に答える