クロックサイクルとは何かを完全に理解しようとしているので、誰かに確認または解消して理解を深めてもらいたいテスト例を思いつきました。この単純なコード行、while ループがデバイス上で実行されているとします。
while(true)
{
int x = 5;
}
コマンド: int x = 5 はクロック サイクルごとに 1 回実行されますか? つまり、クロック速度は、デバイスが単位時間あたりにコマンドを読み取って実行できる速度ですか?
クロックサイクルとは何かを完全に理解しようとしているので、誰かに確認または解消して理解を深めてもらいたいテスト例を思いつきました。この単純なコード行、while ループがデバイス上で実行されているとします。
while(true)
{
int x = 5;
}
コマンド: int x = 5 はクロック サイクルごとに 1 回実行されますか? つまり、クロック速度は、デバイスが単位時間あたりにコマンドを読み取って実行できる速度ですか?
クロック サイクルは、プロセッサのロジックを駆動するオシレータの 1 つのサイクルです。プロセッサがそのサイクルで達成できることは、プロセッサのアーキテクチャや、メモリ速度などの他の要因によって異なります。
あなたの例のコードは高水準言語であり、直接翻訳するとほぼ確実に複数のマシンレベルの命令に変換されます。たとえば、疑似マシンコードでは:
loop:
MOV addrx,#5
JMP loop
これは、ループごとに少なくとも 2 マシン サイクルになります。高レベル コードと生成された機械語命令との間に決定論的な関係はほとんど、またはまったくありません。この単純なケースでは、そう見えるかもしれません。
この問題は、命令セットがプロセッサによってどのように実装されるかによってさらに複雑になります。一般的な RISC プロセッサは 1 つの命令を 1 サイクルで実行しますが、CISC プロセッサでは、複雑さに応じて個々の命令が異なる数のサイクルを必要とします。
もう 1 つの考慮事項は、メモリ バスのレイテンシです。多くの場合、プロセッサはメモリにアクセスするよりも高速に命令を実行できます。これは特にフラッシュ メモリに当てはまります。より遅いメモリにアクセスする命令は、データが到着するまでプロセッサが停止する待機状態を導入する可能性があります。
一部のプロセッサには、命令を並列に実行する機能があり、1 つのサイクルで複数の命令を実行できます。また、異なるデータに対して同じ操作を同時に実行できる SIMD (single instruction-multiple data) 命令を使用するものもあります。
命令のスループットに影響を与えるもう 1 つの手法は、パイプライン処理です。これは、命令が複数のサイクルを必要とする場合がありますが、各サイクルで新しい命令を開始できます。たとえば、5 つの 4 サイクル命令が次々に開始された場合、結果は 1 回生成されます。サイクルごと。
一部のプロセッサは、個別のバスを使用してデータと命令の同時フェッチを可能にするハーバード アーキテクチャを採用しています。
分岐予測などの命令スループットを維持するために、他の手法が使用されます。高級言語コンパイラは、多くの場合、上記のすべての手法の可能性を最大化するコードを生成します。
多くの場合、特定のアーキテクチャに対して与えられるパフォーマンスの尺度は MIPS/MHz です。これは、クロック サイクルごとに通常実行される命令の数を示します (多くのクロック サイクルで償却されます)。たとえば、ARM Cortex-M3 は 1.25 MIPS/MHz を管理し、Renesas SH-4 は 1.8 MIPS/MHz を達成します。
どこから始めれば...
どのプロセッサにも「クロック」があり、電子機器のビットが次のことが起こる前に、ある状態から別の状態に遷移する時間を確保します。最新のデバイスの速度では、「瞬間的」なものはありません。「ステップ」は「勾配」になり、非常に短いトレースでも電気信号の伝送に遅延が発生します。
CPU のアーキテクチャに応じて、特定の操作を「1 クロック サイクルで」実行できますが、他の操作は「複数のサイクル」で実行できます。長い除算を考えてみてください。一連の減算 - シフト演算を実行します。演算の前の部分が完了するまで、次に何をする必要があるかわかりません。さらに、1 サイクルで完全な操作を達成する方法を簡単に確認できます。
特定の「高レベル」命令が機械語コードに変換されると、結果のコードは 1 つまたは複数のサイクルを要し、単純な命令は 1 つまたは複数のステップを要します。コンパイラ、ターゲット、および選択した最適化に応じて、上記のコードで次のいずれかが発生する可能性があります。
コンパイラは、「while」条件が常に真であり、ループ内で何も変化しないことを認識しています。さらに、x の値を決して使用しないことを認識し、命令をまったく実装しないことを選択します。
int
コンパイラは、変数に組み込みレジスタを使用することを決定しx
、コンパイル時に初期化します。ループの実行に時間がかからない
コンパイラは '5' をレジスタにロードし、テーブルで x のオフセットを検索し、ポインタを計算し、レジスタをオフセット アドレスにコピーします。サイクル数はいくつでもかまいません。
これが本当に役に立ったかどうかはわかりませんが、質問はかなり複雑です...
残念ながら、あなたが提案したほど単純ではありません。
関連するウィキペディアの記事http://en.wikipedia.org/wiki/Sequential_logicをご覧ください。
簡単に言えば、クロックサイクルとは、同期的に動作する回路が定義された1つの状態から次の定義された状態に切り替わるのにかかる時間です。
実際のところ、多くの場合、CPU が命令を実行するのにかかる時間に関連しています。CPU のマニュアルを参照することをお勧めします。実行時間は、多くの場合、目的の命令を実行するのにかかるクロック サイクル数として示されます。
残念ながら、実際にはそれほど単純ではありません。特別な要件を満たせば、いくらか賢い CPU が命令をより高速に実行できるようになるからです。たとえば、命令パイプラインを介して命令をプッシュすることにより、CPU は次の命令で動作を開始している可能性がありますが、1 クロック サイクル以上かかる前の命令の一部がまだ処理されています。
命令の並べ替えによってプログラム フローが変更されない場合、または命令が投機的に事前に計算される場合、命令が並べ替えられる可能性さえあります。
一方、命令をメモリからフェッチする必要がある場合は、1 つの命令が動作するのにクロック サイクルで考えると、はるかに長い時間がかかる場合があります。