中断することなくプログラムを最初から最後まで実行するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/1215713

  •  06-07-2019
  •  | 
  •  

質問

Ubuntu 8.10でRDTSCを使用してコードの時間を計測しようとしています(私が試した他のプロファイリングソフトウェアは、必要な解像度に時間を合わせることができません)。ただし、タスクスイッチから異常値を取得し続け、発火を中断すると、統計が無効になります。

プログラムが数ミリ秒で実行されることを考慮して、環境内のすべての割り込み(本質的にタスクスイッチをオフにする)を無効にすることは可能ですか?または、より多くの電力を使用できるOSに移動する必要がありますか?自分のOSカーネルを使用してこのタイミングコードを実行した方が良いでしょうか?アルゴリズムの最高/最悪のケースのパフォーマンスを証明しようとしていますので、タイミングに関して完全に安定している必要があります。

現在使用している関連コードは次のとおりです。

inline uint64_t rdtsc()
{
    uint64_t ret;
    asm volatile("rdtsc" : "=A" (ret));
    return ret;
}

void test(int readable_out, uint32_t start, uint32_t end, uint32_t (*fn)(uint32_t, uint32_t))
{
    int i;
    for(i = 0; i <= 100; i++)
    {
        uint64_t clock1 = rdtsc();
        uint32_t ans = fn(start, end);
        uint64_t clock2 = rdtsc();

        uint64_t diff = clock2 - clock1;

        if(readable_out)
            printf("[%3d]\t\t%u [%llu]\n", i, ans, diff);
        else
            printf("%llu\n", diff);
    }
}

追加のポイントは、このコードでオーバーフロー状態を適切に処理していないことに気づいた人たちです。この段階では、プログラムがタイムスライスを失うために突然ジャンプすることなく、一貫した出力を取得しようとしています。

私のプログラムのナイス値は-20です。

要約すると、OSからの中断なしにこのコードを実行することは可能ですか?または、ring0のベアハードウェアで実行する必要があるので、IRQとスケジューリングを無効にできますか?事前に感謝します!

役に立ちましたか?

解決

nanosleep()を呼び出して、テストの各反復の直前に1秒程度スリープする場合、<!> quot; fresh <!> quot;を取得する必要があります。各テストのタイムスライス。 100HZタイマー割り込みを使用してカーネルをコンパイルし、タイマー機能が10ミリ秒未満で完了する場合、タイマー割り込みがそのようにヒットするのを回避できるはずです。

他の割り込みを最小限に抑えるには、すべてのネットワークデバイスを構成解除し、スワップなしでシステムを構成し、それ以外の場合は休止状態であることを確認します。

他のヒント

トリッキー。オペレーティングシステムを「オフ」にして、厳密なスケジューリングを保証することはできないと思います。

これを逆さまにします。非常に高速で実行されるため、何度も実行して結果の分布を収集します。標準のUbuntu Linuxは狭義のリアルタイムOSではないことを考えると、すべての代替アルゴリズムは同じセットアップで実行されます-そして、分布を比較できます(サマリー統計から変位値、qqplotsまで何でも使用できます)。この比較は、Python、R、またはOctaveのいずれかで行うことができます。

FreeDOS を実行して逃げることができるかもしれません。 /groups.google.com/group/alt.os.free-dos/browse_thread/thread/e35dec94e75ca33b?pli=1 "rel =" nofollow noreferrer ">単一プロセスOS 。

2番目のリンクの関連テキストは次のとおりです。

  

MicrosoftのDOS実装、これはde   DOSシステムの事実上の標準   x86ワールド、シングルユーザー、   シングルタスクオペレーティングシステム。それ   ハードウェアへの生のアクセスを提供し、   OS APIの最小限のレイヤーのみ   ファイルI / Oなど。これは   組み込みに関しては良いこと   システム。多くの場合、必要なのは   なしで何かを成し遂げるために   あなたの方法でオペレーティングシステム。

     

DOSには(本来)の概念がありません   スレッドと複数の概念なし、   進行中のプロセス。応用   ソフトウェアは経由でシステムコールを行います   割り込みインターフェイスの使用、呼び出し   処理するさまざまなハードウェア割り込み   ビデオやオーディオのようなもの、そして   処理するソフトウェア割り込みの呼び出し   読書のような様々なもの   ディレクトリ、ファイルの実行など   

もちろん、エミュレータではなく実際のハードウェアでFreeDOSを実際に起動すると、おそらく最高のパフォーマンスが得られます。

実際にFreeDOSを使用したことはありませんが、プログラムは標準Cのように見えるので、FreeDOS用の標準コンパイラは何でも使用できると思います。

プログラムがミリ秒単位で実行され、Linux上で実行されている場合、 タイマー周波数(Linuxの場合)が100Hz(1000Hzではない)に設定されていることを確認してください。 (cd / usr / src / linux; menuconfigを作成し、<!> quot;プロセッサタイプと機能<!> quot;-<!> gt; <!> quot;タイマー周波数<!> quot;を確認してください。) これにより、CPUは10ミリ秒ごとに中断されます。

さらに、LinuxのデフォルトのCPUタイムスライスは100ミリ秒であるため、-20のナイスレベルでは、数ミリ秒実行している場合にスケジュールが解除されません。

また、fn()で101回ループしています。システムを適切に調整するために、fn()を何もしないことを検討してください。

何度も印刷するのではなく、統計(平均+ stddev)を作成します(スケジュールされたタイムスライスを消費し、ターミナルは最終的にスケジュールなどを取得します...それを避けます)。

RDTSCベンチマークサンプルコード

chrt -f 99 ./test を使用して、リアルタイムの最大優先度で./testを実行できます。そうすれば、少なくとも他のユーザー空間プロセスによって中断されることはありません。

また、 linux-rt パッケージをインストールすると、リアルタイムカーネルがインストールされます。これにより、スレッド割り込みを介した割り込みハンドラーの優先度をより詳細に制御できます。

rootとして実行する場合、sched_setscheduler()を呼び出して、リアルタイムの優先度を自分で設定できます。ドキュメントを確認してください。

Linuxでプリエンプティブスケジューリングを無効にする方法があるかもしれませんが、必要ではないかもしれません。 /proc/<pid>/schedstatまたは/procの他のオブジェクトからの情報を使用して、プリエンプトされたタイミングを検知し、それらのタイミングサンプルを無視することができます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top