2017-02-17 10 views
2

私は現在のスレッドが今まで実行していた時間を知ろうとしています。私はそれにgetrusage(RUSAGE_THREAD, &r_usage);を使用しようとしています。ここに私の混乱は、以下のとおりです。getrusage(RUSAGE_THREAD、&r_usage)でのユーザーCPU時間とシステムCPU時間は、どのくらい効果的ですか?

1-この関数によって返された時間は、スレッドがブロックされた(例えば、条件変数の場合)またはアウト予定されて過ごした時間は含まれていますか?

2スレッドが他の理由でブロックされた時間はどのくらいですか? I/Oがブロックされていますか?

3-私はgetrusage(RUSAGE_THREAD, &r_usage);はナノ秒でそれを返すために作るために時間精度を高めることができますか?

多くの感謝!

+0

なぜナノ秒の精度が必要ですか?コンテキストスイッチには数マイクロ秒かかるので、すでにCSWのためにマイクロ秒の大きさのエラーがある – myaut

+0

カーネルに 'CONFIG_SCHED_DEBUG'が設定されている場合は、スレッドの'/proc/sched_debug'で 'sum_exec_runtime'を確認しようとします – myaut

答えて

2

いいえ、一般的にブロックされた時は、(対策を何のrusageである)、ユーザまたはカーネルCPU時間に割り当てることはありません。 rusageタイマーは、基本的にはOSによって起動され、停止される「ウォールクロックタイマー」です。プロセスがスケジュールされると時刻が記録され、スケジュール解除されると停止します(同様に、エントリ/終了時のユーザー/カーネルの分割カーネルルーチンへ)。これらのセグメントの合計はCPU時間です。いくつかのケースでは

は、IOのように、カーネルは、実際の仕事をして待っていないと、それはあなたのプロセスに割り当ててもよいかもしれません。

CPU時間がの場合は、パフォーマンスカウンタを調べてください。 Linuxでは、あなたが始めるために仮想化された方法でこれらのカウンタにアクセスするためのperf_eventsシステムを使用するか、またはこのサブシステムへのアクセスをラップPAPIのようなライブラリを使用するか、またはおそらく最も簡単なことができます簡単なカウンタのアクセスを提供しlibpfcのような軽量のものを使用することです。

また尋ねる:

また

、どのように私はI/Oに費やされた時間を含めることができますか?

現代のシステムではIOの非同期性とキャッシュされた性質のため、これは厳しい質問です。それは、消費された時間と割り当て方法を厳密にピン止めするのは難しいです(たとえば、あるプロセスがディスクからキャッシュにページを持ってきたが、その後10個の別のプロセスがそれにアクセスする場合、IO時間をどのように分割するのか)。あなたが考えることができると思うのは、/proc/pid/カウンターとステータス入力を調べることです。おそらくIOオンブロックインジケーターがあります。実際、topはこの状態のプロセスを表示することができるので、これを/proc/$pidから得ることができます。このファイルシステムを他のスレッドからサンプリングしてその作業を行う必要があることに注意してください。

また、アプリケーションレベルでIOコールを計測することもできます。最後に、Linux上でptraceまたはより新しいFTraceのようなものを使用して、IO呼び出しのカーネルレベルで計測することができます。おそらくこれをプロセスでフィルタリングできます。新しいカーネルには "プロセス単位のIOアカウンティング"があるようですが、すぐに適切なリンクを見つけることができませんでした。おそらく、iotopのソースには、必要な呼び出しがあります。

最後に、現在のスレッドが今まで実行していた時間の意味に依存します。:IOを含める場合は、スレッドが開始されてからウォールクロック時間が必要なのでしょうか?その後、clock_gettimeと、ナノ秒の解像度を提供する友人(公称では、呼び出しには少なくとも12ナノ秒かかるので、1〜2ナノ秒を正確に測定することはありません)を使用できます。

2

(何らかの理由で)ブロックされた時間が時間が実行に費やさとして課金されるだろうと信じてするのは難しいようだ - しかし、それがあることをオフのチャンスに、のアイデアを得るために迅速な実験を行いましょう:

#include <unistd.h> 
#include <sys/time.h> 
#include <sys/resource.h> 
#include <iostream> 
#include <iomanip> 

std::ostream &operator<<(std::ostream &os, timeval const &t) { 
    return os << t.tv_sec << '.' << std::setw(6) << std::setfill('0') << t.tv_usec << std::setfill(' '); 
} 

int main() { 
    rusage r; 

    getrusage(RUSAGE_THREAD, &r); 
    std::cout << r.ru_utime << " [" << r.ru_stime << "]\n"; 
    sleep(10); 
    getrusage(RUSAGE_THREAD, &r); 
    std::cout << r.ru_utime << " [" << r.ru_stime << "]\n"; 
} 

結果:

0.000000 [0.000000] 
0.000000 [0.000000] 

ので、寝て過ごした時間は、充電されていません。 mutexで同様のテストを行うことができます:

#include <sys/time.h> 
#include <sys/resource.h> 
#include <iostream> 
#include <iomanip> 
#include <thread> 
#include <mutex> 

using namespace std::literals; 

std::ostream &operator<<(std::ostream &os, timeval const &t) { 
    return os << t.tv_sec << '.' << std::setw(6) << std::setfill('0') << t.tv_usec << std::setfill(' '); 
} 

int main() { 
    rusage r; 

    getrusage(RUSAGE_THREAD, &r); 
    std::cout << r.ru_utime << " [" << r.ru_stime << "]\n" << std::flush; 

    std::mutex m; 
    m.try_lock(); // ensure mutex is locked 

    // create thread to unlock mutex after 5 seconds: 
    auto t = std::thread([&]{ std::this_thread::sleep_for(5s); m.unlock(); }); 

    // wait for mutex to be unlocked 
    m.lock(); 

    // re-check resource usage 
    getrusage(RUSAGE_THREAD, &r); 
    std::cout << r.ru_utime << " [" << r.ru_stime << "]\n"; 
    t.join(); 
} 

これも同様の結果が得られます。私は条件変数のためにそれを繰り返すのに気にしませんでしたが、私はそれと別の結果を見て驚くでしょう(コンデバーは常にミューテックスに関連付けられています、そして、あなたが本当に待っているミューテックスです)。

これは、I/Oの可能なすべての種類をテストしようとするあまり実用的だが、過去の経験は同じがそれで真実であることを示している:I/Oは、時間の実行として扱われていないため、時間ブロックさが待っています。

は理論的にはナノ秒の範囲で精度を向上させることができますが、スイッチを反転するか別の機能を呼び出すだけでなく、カーネルの書き換えが必要になると思います。現実的には、が多くてもをより正確に得ることができるかどうかという疑問が多くあります。ナノ秒レベルの精度が必要な場合、これはおそらく仕事のための適切な種類のツールではありません。

+0

コードの詳細な回答をありがとうございました。ナノ秒の範囲で別のツールをお勧めしますか?または、他の方法で、あなたはこの仕事をするのが良いと思いますか?さらに、I/Oに費やされる時間をどのように含めることができますか? –

+1

@DIMIA:プロファイラを使ってみましたか?(例: 'g ++ -pg foo.cpp'、次に' gprof a.out'?)公正な警告:これをうまく使用する方法を学ぶのに時間と労力がかかります –

+0

実際に私プロファイラを自分で作成しており、これは私が行う計算の一部です。 –

関連する問題