簡體   English   中英

getrusage(RUSAGE_THREAD,&r_usage)中的用戶CPU時間和系統CPU時間分別是什么?

[英]What do the user CPU time and system CPU time in getrusage(RUSAGE_THREAD, &r_usage) measure excactly?

所以我想知道到目前為止當前線程已執行的時間。 我正在嘗試使用getrusage(RUSAGE_THREAD, &r_usage); 為了它。 這是我的困惑:

1-該函數返回的時間是否包括線程被阻塞(例如,在條件變量上)或計划外的時間?

2-由於其他原因(例如因I / O阻塞)而導致線程阻塞的時間如何?

3-我可以增加制作getrusage(RUSAGE_THREAD, &r_usage);的時間精度getrusage(RUSAGE_THREAD, &r_usage); 在十億分之一秒內返回它?

非常感謝!

似乎很難相信(無論出於何種原因)所花費的時間(由於任何原因)都將花費在執行時間上,但是,如果有這樣的機會,讓我們做一個快速實驗來弄個主意:

#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]

因此,不花時間睡覺。 我們可以使用互斥量進行類似的測試:

#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();
}

這給出了相似的結果。 我並沒有為條件變量重復它​​,但是我很驚訝地看到它的不同結果(condvar總是與互斥鎖相關聯,而這正是您真正等待的互斥鎖)。

嘗試測試每種可能的I / O都不太實用,但是過去的經驗表明,情況也是如此:等待I / O的時間阻塞不視為時間執行。

就准確性而言,我想您可以在理論上將精度提高到納秒級,但這將涉及重寫內核,而不僅僅是翻轉開關或調用其他函數。 實際上,它是開放了很多問題,你是否會能夠得到准確甚至然后。 如果您需要納秒級的精度,那么這可能不是正確的工具。

不,通常情況下,阻塞時間不會分配給用戶或內核CPU時間(這是使用率衡量的時間)。 rusage計時器基本上是一個由操作系統啟動和停止的“掛鍾計時器”:安排進程時,它會記下時間,而安排時間表時,它會記下時間(對於進入/退出時用戶/內核分裂的情況類似到內核​​例程)。 所有這些段的總和就是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和friends(名義上,但是調用本身至少需要十幾納秒,因此您不會精確地測量耗時1或2納秒的東西)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM