使用线程时测量执行时间

时间:2019-05-16 14:08:48

标签: c++ multithreading time measure

我想测量一些代码的执行时间。该代码从main()函数开始,并在事件处理程序中结束。

我有一个C ++ 11代码,如下所示:

    HMGET myHash key1 key2 key3

    tab = {
        key1 = myHash [1]
        key2 = myHash [2]
        key3 = myHash [3]
    }

因此可以保证EventHandler()仅被调用一次,并且仅在instance-> start()调用之后被调用。

它正在工作,这段代码给了我一些输出,但这是一个可怕的代码,它使用全局变量和不同的线程访问全局变量。但是我无法更改使用的API(构造函数,即线程调用EventHandler的方式)。

我想问一下是否存在更好的解决方案。

谢谢。

3 个答案:

答案 0 :(得分:1)

全局变量是不可避免的,只要MyClass希望使用普通函数,并且无法将某些上下文指针与函数一起传递...

尽管如此,您可以以更简洁的方式编写代码:

#include <future>
#include <thread>
#include <chrono>
#include <iostream>

struct MyClass
{
    typedef void (CallbackFunc)();

    constexpr explicit MyClass(CallbackFunc* handler)
     : m_handler(handler)
    {
    }

    void Start()
    {
        std::thread(&MyClass::ThreadFunc, this).detach();
    }

private:
    void ThreadFunc()
    {
        std::this_thread::sleep_for(std::chrono::seconds(5));
        m_handler();
    }

    CallbackFunc*     m_handler;
};


std::promise<std::chrono::time_point<std::chrono::high_resolution_clock>>   gEndTime;

void EventHandler()
{
    gEndTime.set_value(std::chrono::high_resolution_clock::now());
}


int main()
{
    MyClass         task(EventHandler);

    auto            trigger = gEndTime.get_future();
    auto            startTime = std::chrono::high_resolution_clock::now();
    task.Start();
    trigger.wait();

    std::chrono::duration<double>   diff = trigger.get() - startTime;

    std::cout << "Duration = " << diff.count() << " secs." << std::endl;

    return 0;
}

答案 1 :(得分:0)

clock()调用不会过滤掉调度程序与程序事件处理程序线程并行运行的不同进程和线程的执行。还有替代方法,例如time()和getrusage(),它们告诉cpu处理时间。尽管没有明确提及这些调用的线程行为,但是如果是Linux,则将线程视为进程,但必须对其进行研究。

答案 2 :(得分:0)

clock()在这里是错误的工具,因为它没有计算CPU运行操作所需的实际时间,例如,如果线程根本没有运行,则仍在计算时间。 / p>

相反,您必须使用平台特定的API,例如pthread_getcpuclockid用于POSIX兼容的系统(检查是否定义了_POSIX_THREAD_CPUTIME),该API计算特定线程花费的实际时间。

您可以看看我为C ++编写的benchmarking library,它支持线程感知测量(请参阅struct thread_clock实现)。

或者,您可以使用man page中的代码段:

/* Link with "-lrt" */

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>

#define handle_error(msg) \
        do { perror(msg); exit(EXIT_FAILURE); } while (0)

#define handle_error_en(en, msg) \
        do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

static void *
thread_start(void *arg)
{
    printf("Subthread starting infinite loop\n");
    for (;;)
        continue;
}

static void
pclock(char *msg, clockid_t cid)
{
    struct timespec ts;
    printf("%s", msg);
    if (clock_gettime(cid, &ts) == -1)
        handle_error("clock_gettime");
    printf("%4ld.%03ld\n", ts.tv_sec, ts.tv_nsec / 1000000);
}

int
main(int argc, char *argv[])
{
    pthread_t thread;
    clockid_t cid;
    int j, s;

    s = pthread_create(&thread, NULL, thread_start, NULL);
    if (s != 0)
        handle_error_en(s, "pthread_create");

    printf("Main thread sleeping\n");
    sleep(1);

    printf("Main thread consuming some CPU time...\n");
    for (j = 0; j < 2000000; j++)
        getppid();

    pclock("Process total CPU time: ", CLOCK_PROCESS_CPUTIME_ID);

    s = pthread_getcpuclockid(pthread_self(), &cid);
    if (s != 0)
        handle_error_en(s, "pthread_getcpuclockid");

    pclock("Main thread CPU time:   ", cid);

    /* The preceding 4 lines of code could have been replaced by:
    pclock("Main thread CPU time:   ", CLOCK_THREAD_CPUTIME_ID); */

    s = pthread_getcpuclockid(thread, &cid);
    if (s != 0)
        handle_error_en(s, "pthread_getcpuclockid");
    pclock("Subthread CPU time: 1    ", cid);

    exit(EXIT_SUCCESS);         /* Terminates both threads */
}