このスレッドの Linus によると:
1%オフくらいなら大丈夫です。誰かが遅延の小さなエラーに敏感な遅延値を選択した場合、または 5% のようなエラーにさえ気付いた場合、選択した遅延は短すぎます。
udelay() は、ある種の精密機器を意図したものではありませんでした。特に CPU が異なる周波数で実行されている場合、歴史的にかなり大きな変動がありました。従来のビジー ループは、割り込みだけでなく、キャッシュ アラインメント (以前はインライン化していました) などの影響も受けます。その後、TSC ベースのループは、明らかに TSC が安定しているかどうかに依存していました (これは、その間)。
歴史的に、udelay() が本当にオフ (つまり 50% オフなど) であるのを見てきました。1% の範囲のことについては心配しません。
ライナス
だから完璧にはなりません。オフになります。どれだけ多くの要因に依存しています。for
ループを使用する代わりに、代わりに使用することを検討してくださいmdelay
。もう少し正確かもしれません。O'Reilly Linux Device Drivers bookから:
udelay呼び出しは、 の精度がわずか 8 ビットであり、長い遅延を計算すると顕著なエラーが累積するため、短い時間の経過に対してのみ呼び出す必要があります。loops_per_second
最大許容遅延はほぼ 1 秒ですが (遅延が長くなると計算がオーバーフローするため)、udelayの推奨最大値は 1000 マイクロ秒 (1 ミリ秒) です。関数mdelayは、遅延が 1 ミリ秒より長くなければならない場合に役立ちます。
udelayはビジー待機関数であることを覚えておくことも重要です (したがって、 mdelayもそうです)。タイムラプス中は他のタスクを実行できません。したがって、特にmdelayを使用する場合は十分に注意し、目的を達成する方法が他にない場合を除き、使用を避ける必要があります。
現在、数マイクロ秒より長く、タイマー ティックより短い遅延のサポートは非常に非効率的です。遅延は、人間またはハードウェアが気付くのに十分な長さである必要があるため、これは通常は問題になりません。100 分の 1 秒は、人間に関連する時間間隔に適した精度ですが、1 ミリ秒は、ハードウェア アクティビティの十分な長さの遅延です。
具体的には、「udelayの推奨最大値は 1000 マイクロ秒 (1 ミリ秒)です」という行が突き出ています。これは、2000 が最大であると述べているためです。遅延の挿入に関するこのドキュメントから:
mdelay は udelay のマクロ ラッパーで、大きな引数を udelay に渡すときにオーバーフローの可能性を考慮します。
そのため、オーバーフロー エラーが発生している可能性があります。私は通常、2000年が「大きな議論」であるとは考えていません.
しかし、タイミングに本当の精度が必要な場合は、自分が持っているようにオフセットを処理するか、独自にロールするか、別のカーネルを使用する必要があります。アセンブラーまたはハード リアルタイム カーネルを使用して独自の遅延関数をロールする方法については、高解像度タイミングに関するこの記事を参照してください。
参照: Linux カーネル: udelay() の戻りが早すぎる?