获取指定代码段的cpu占用[linux][windows][c++]

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;
}

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值