C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > C++获取cpu占用

C++实现获取指定代码段的cpu占用

作者:BuffaloX_X

这篇文章主要为大家详细介绍了C++实现获取指定代码段的cpu占用的相关知识,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下

windows

#include <iostream>
#include <windows.h>
#include <vector>
 
class CodeSegmentCPUMonitor {
public:
    static CodeSegmentCPUMonitor& getInstance() {
        static CodeSegmentCPUMonitor instance;
        return instance;
    }
 
    ~CodeSegmentCPUMonitor() {
        // 获取结束性能计数器值
        QueryPerformanceCounter(&endCounter);
 
        // 计算运行时间(秒)
        double elapsedTime = static_cast<double>(endCounter.QuadPart - startCounter.QuadPart) / frequency.QuadPart;
 
        // 计算 CPU 平均占用
        double averageCPUUsage = (totalCycles / elapsedTime) * 100.0 / processorSpeed;
 
        std::cout << "Total Average CPU Usage: " << averageCPUUsage << "%\n";
    }
 
    void enterCodeSegment() {
        // 进入代码段时记录开始时间
        QueryPerformanceCounter(&codeSegmentStartCounter);
    }
 
    void exitCodeSegment() {
        // 退出代码段时记录结束时间
        QueryPerformanceCounter(&codeSegmentEndCounter);
 
        // 计算代码段的 CPU 占用
        ULONGLONG codeSegmentCycles = codeSegmentEndCounter.QuadPart - codeSegmentStartCounter.QuadPart;
        totalCycles += codeSegmentCycles;
    }
 
private:
    LARGE_INTEGER frequency;
    LARGE_INTEGER startCounter;
    LARGE_INTEGER endCounter;
 
    LARGE_INTEGER codeSegmentStartCounter;
    LARGE_INTEGER codeSegmentEndCounter;
 
    ULONGLONG totalCycles = 0;
 
    // 假设处理器速度为 2.5 GHz,你需要根据实际情况调整这个值
    const double processorSpeed = 2.5e9;
 
    CodeSegmentCPUMonitor() {
        // 获取性能计数器频率
        if (QueryPerformanceFrequency(&frequency)) {
            // 获取初始性能计数器值
            QueryPerformanceCounter(&startCounter);
        } else {
            std::cerr << "Failed to get performance counter frequency.\n";
        }
    }
 
    // 禁用拷贝构造函数和赋值运算符
    CodeSegmentCPUMonitor(const CodeSegmentCPUMonitor&) = delete;
    CodeSegmentCPUMonitor& operator=(const CodeSegmentCPUMonitor&) = delete;
};
 
int main() {
    // Example: Measure CPU usage for code segment 1
    {
        CodeSegmentCPUMonitor::getInstance().enterCodeSegment();
 
        // Your code segment 1 here
 
        CodeSegmentCPUMonitor::getInstance().exitCodeSegment();
    }
 
    // Example: Measure CPU usage for code segment 2
    {
        CodeSegmentCPUMonitor::getInstance().enterCodeSegment();
 
        // Your code segment 2 here
 
        CodeSegmentCPUMonitor::getInstance().exitCodeSegment();
    }
 
    // ... Add more code segments as needed ...
 
    return 0;
}

linux

#include <iostream>
#include <vector>
#include <ctime>
 
class CodeSegmentCPUMonitor {
public:
    static CodeSegmentCPUMonitor& getInstance() {
        static CodeSegmentCPUMonitor instance;
        return instance;
    }
 
    ~CodeSegmentCPUMonitor() {
        // 获取结束时间
        struct timespec endTime;
        clock_gettime(CLOCK_MONOTONIC, &endTime);
 
        // 计算运行时间(秒)
        double elapsedTime = static_cast<double>(endTime.tv_sec - startTime.tv_sec) +
                             static_cast<double>(endTime.tv_nsec - startTime.tv_nsec) / 1e9;
 
        // 计算 CPU 平均占用
        double averageCPUUsage = (totalCycles / elapsedTime) * 100.0 / processorSpeed;
 
        std::cout << "Total Average CPU Usage: " << averageCPUUsage << "%\n";
    }
 
    void enterCodeSegment() {
        // 进入代码段时记录开始时间
        clock_gettime(CLOCK_MONOTONIC, &codeSegmentStartTime);
    }
 
    void exitCodeSegment() {
        // 退出代码段时记录结束时间
        struct timespec codeSegmentEndTime;
        clock_gettime(CLOCK_MONOTONIC, &codeSegmentEndTime);
 
        // 计算代码段的 CPU 占用
        double codeSegmentElapsedTime = static_cast<double>(codeSegmentEndTime.tv_sec - codeSegmentStartTime.tv_sec) +
                                        static_cast<double>(codeSegmentEndTime.tv_nsec - codeSegmentStartTime.tv_nsec) / 1e9;
        totalCycles += codeSegmentElapsedTime;
    }
 
private:
    struct timespec startTime;
    struct timespec codeSegmentStartTime;
 
    double totalCycles = 0;
 
    // 假设处理器速度为 2.5 GHz,你需要根据实际情况调整这个值
    const double processorSpeed = 2.5e9;
 
    CodeSegmentCPUMonitor() {
        // 获取初始时间
        clock_gettime(CLOCK_MONOTONIC, &startTime);
    }
 
    // 禁用拷贝构造函数和赋值运算符
    CodeSegmentCPUMonitor(const CodeSegmentCPUMonitor&) = delete;
    CodeSegmentCPUMonitor& operator=(const CodeSegmentCPUMonitor&) = delete;
};
 
int main() {
    // Example: Measure CPU usage for code segment 1
    {
        CodeSegmentCPUMonitor::getInstance().enterCodeSegment();
 
        // Your code segment 1 here
 
        CodeSegmentCPUMonitor::getInstance().exitCodeSegment();
    }
 
    // Example: Measure CPU usage for code segment 2
    {
        CodeSegmentCPUMonitor::getInstance().enterCodeSegment();
 
        // Your code segment 2 here
 
        CodeSegmentCPUMonitor::getInstance().exitCodeSegment();
    }
 
    // ... Add more code segments as needed ...
 
    return 0;
}

linux和windows条件编译

#include <iostream>
 
#ifdef _WIN32
#include <windows.h>
#else
#include <ctime>
#endif
 
class CodeSegmentCPUMonitor {
public:
    static CodeSegmentCPUMonitor& getInstance() {
        static CodeSegmentCPUMonitor instance;
        return instance;
    }
 
    ~CodeSegmentCPUMonitor() {
#ifdef _WIN32
        FILETIME endTime;
        GetSystemTimeAsFileTime(&endTime);
        ULARGE_INTEGER endTime64;
        endTime64.LowPart = endTime.dwLowDateTime;
        endTime64.HighPart = endTime.dwHighDateTime;
        double elapsedTime = static_cast<double>(endTime64.QuadPart - startTime.QuadPart) / frequency.QuadPart;
#else
        struct timespec endTime;
        clock_gettime(CLOCK_MONOTONIC, &endTime);
        double elapsedTime = static_cast<double>(endTime.tv_sec - startTime.tv_sec) +
                             static_cast<double>(endTime.tv_nsec - startTime.tv_nsec) / 1e9;
#endif
 
        double averageCPUUsage = (totalCycles / elapsedTime) * 100.0 / processorSpeed;
 
        std::cout << "Total Average CPU Usage: " << averageCPUUsage << "%\n";
    }
 
    void enterCodeSegment() {
#ifdef _WIN32
        GetSystemTimeAsFileTime(&codeSegmentStartTime);
#else
        clock_gettime(CLOCK_MONOTONIC, &codeSegmentStartTime);
#endif
    }
 
    void exitCodeSegment() {
#ifdef _WIN32
        FILETIME codeSegmentEndTime;
        GetSystemTimeAsFileTime(&codeSegmentEndTime);
        ULARGE_INTEGER codeSegmentEndTime64;
        codeSegmentEndTime64.LowPart = codeSegmentEndTime.dwLowDateTime;
        codeSegmentEndTime64.HighPart = codeSegmentEndTime.dwHighDateTime;
        double codeSegmentElapsedTime = static_cast<double>(codeSegmentEndTime64.QuadPart - codeSegmentStartTime.QuadPart) / frequency.QuadPart;
#else
        struct timespec codeSegmentEndTime;
        clock_gettime(CLOCK_MONOTONIC, &codeSegmentEndTime);
        double codeSegmentElapsedTime = static_cast<double>(codeSegmentEndTime.tv_sec - codeSegmentStartTime.tv_sec) +
                                        static_cast<double>(codeSegmentEndTime.tv_nsec - codeSegmentStartTime.tv_nsec) / 1e9;
#endif
 
        totalCycles += codeSegmentElapsedTime;
    }
 
private:
#ifdef _WIN32
    LARGE_INTEGER frequency;
    LARGE_INTEGER startTime;
    FILETIME codeSegmentStartTime;
#else
    struct timespec startTime;
    struct timespec codeSegmentStartTime;
#endif
 
    double totalCycles = 0;
    const double processorSpeed = 2.5e9;
 
    CodeSegmentCPUMonitor() {
#ifdef _WIN32
        QueryPerformanceFrequency(&frequency);
        QueryPerformanceCounter(&startTime);
#else
        clock_gettime(CLOCK_MONOTONIC, &startTime);
#endif
    }
 
    CodeSegmentCPUMonitor(const CodeSegmentCPUMonitor&) = delete;
    CodeSegmentCPUMonitor& operator=(const CodeSegmentCPUMonitor&) = delete;
};
 
int main() {
    // Example: Measure CPU usage for code segment 1
    {
        CodeSegmentCPUMonitor::getInstance().enterCodeSegment();
 
        // Your code segment 1 here
 
        CodeSegmentCPUMonitor::getInstance().exitCodeSegment();
    }
 
    // Example: Measure CPU usage for code segment 2
    {
        CodeSegmentCPUMonitor::getInstance().enterCodeSegment();
 
        // Your code segment 2 here
 
        CodeSegmentCPUMonitor::getInstance().exitCodeSegment();
    }
 
    // ... Add more code segments as needed ...
 
    return 0;
}

解耦log接口的形式1

#include <iostream>
#include <string>
 
// CPU Monitor Output Interface
class CPUMonitorOutputInterface {
public:
    virtual ~CPUMonitorOutputInterface() {}
    virtual void log(const std::string& message) = 0;
};
 
// ConsoleLogger: 实现CPUMonitorOutputInterface的一个Logger类示例
class ConsoleLogger : public CPUMonitorOutputInterface {
public:
    void log(const std::string& message) override {
        std::cout << "Logger: " << message << std::endl;
    }
};
 
class CodeSegmentCPUMonitor {
public:
    CodeSegmentCPUMonitor(CPUMonitorOutputInterface& logger) : logger(logger) {
#ifdef _WIN32
        QueryPerformanceFrequency(&frequency);
        QueryPerformanceCounter(&startTime);
#else
        clock_gettime(CLOCK_MONOTONIC, &startTime);
#endif
    }
 
    ~CodeSegmentCPUMonitor() {
#ifdef _WIN32
        FILETIME endTime;
        GetSystemTimeAsFileTime(&endTime);
        ULARGE_INTEGER endTime64;
        endTime64.LowPart = endTime.dwLowDateTime;
        endTime64.HighPart = endTime.dwHighDateTime;
        double elapsedTime = static_cast<double>(endTime64.QuadPart - startTime.QuadPart) / frequency.QuadPart;
#else
        struct timespec endTime;
        clock_gettime(CLOCK_MONOTONIC, &endTime);
        double elapsedTime = static_cast<double>(endTime.tv_sec - startTime.tv_sec) +
                             static_cast<double>(endTime.tv_nsec - startTime.tv_nsec) / 1e9;
#endif
 
        double averageCPUUsage = (totalCycles / elapsedTime) * 100.0 / processorSpeed;
        logger.log("Total Average CPU Usage: " + std::to_string(averageCPUUsage) + "%");
    }
 
    void enterCodeSegment() {
#ifdef _WIN32
        GetSystemTimeAsFileTime(&codeSegmentStartTime);
#else
        clock_gettime(CLOCK_MONOTONIC, &codeSegmentStartTime);
#endif
    }
 
    void exitCodeSegment() {
#ifdef _WIN32
        FILETIME codeSegmentEndTime;
        GetSystemTimeAsFileTime(&codeSegmentEndTime);
        ULARGE_INTEGER codeSegmentEndTime64;
        codeSegmentEndTime64.LowPart = codeSegmentEndTime.dwLowDateTime;
        codeSegmentEndTime64.HighPart = codeSegmentEndTime.dwHighDateTime;
        double codeSegmentElapsedTime = static_cast<double>(codeSegmentEndTime64.QuadPart - codeSegmentStartTime.QuadPart) / frequency.QuadPart;
#else
        struct timespec codeSegmentEndTime;
        clock_gettime(CLOCK_MONOTONIC, &codeSegmentEndTime);
        double codeSegmentElapsedTime = static_cast<double>(codeSegmentEndTime.tv_sec - codeSegmentStartTime.tv_sec) +
                                        static_cast<double>(codeSegmentEndTime.tv_nsec - codeSegmentStartTime.tv_nsec) / 1e9;
#endif
 
        totalCycles += codeSegmentElapsedTime;
    }
 
private:
    CPUMonitorOutputInterface& logger;
 
#ifdef _WIN32
    LARGE_INTEGER frequency;
    LARGE_INTEGER startTime;
    FILETIME codeSegmentStartTime;
#else
    struct timespec startTime;
    struct timespec codeSegmentStartTime;
#endif
 
    double totalCycles = 0;
    const double processorSpeed = 2.5e9;
};
 
int main() {
    // Example: Measure CPU usage for code segment 1 with ConsoleLogger
    {
        ConsoleLogger consoleLogger;
        CodeSegmentCPUMonitor monitor(consoleLogger);
        monitor.enterCodeSegment();
 
        // Your code segment 1 here
 
        monitor.exitCodeSegment();
    }
 
    // Example: Measure CPU usage for code segment 2 with ConsoleLogger
    {
        ConsoleLogger consoleLogger;
        CodeSegmentCPUMonitor monitor(consoleLogger);
        monitor.enterCodeSegment();
 
        // Your code segment 2 here
 
        monitor.exitCodeSegment();
    }
 
    // ... Add more code segments as needed ...
 
    return 0;
}

到此这篇关于C++实现获取指定代码段的cpu占用的文章就介绍到这了,更多相关C++获取cpu占用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文