我想测量一些代码的执行时间。代码在main()函数中开始,在事件处理程序中结束。
我有一个看起来像这样的C++11代码:
#include <iostream>
#include <time.h>
...
volatile clock_t t;
void EventHandler()
{
// when this function called is the end of the part that I want to measure
t = clock() - t;
std::cout << "time in seconds: " << ((float)t)/CLOCKS_PER_SEC;
}
int main()
{
MyClass* instance = new MyClass(EventHandler); // this function starts a new std::thread
instance->start(...); // this function only passes some data to the thread working data, later the thread will call EventHandler()
t = clock();
return 0;
}
因此,可以保证EventHandler()只会被调用一次,而且只会在instance->start()调用之后调用。
它正在工作,这段代码给了我一些输出,但它是一个可怕的代码,它使用全局变量,并且不同的线程访问全局变量。然而,我不能改变使用的API (构造函数,线程调用EventHandler的方式)。
我想问一下,是否有更好的解决方案。
谢谢。
发布于 2019-05-16 23:13:40
全局变量是不可避免的,只要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;
}
发布于 2019-05-16 22:46:41
clock()调用不会过滤出调度器与程序事件处理程序线程并行运行的不同进程和线程的执行。还有像time ()和getrusage()这样的替代方法,它们告诉cpu进程的时间。虽然没有明确提到这些调用的线程行为,但如果是Linux,线程将被视为进程,但必须对其进行调查。
发布于 2019-05-16 23:03:55
clock()
在这里是错误的工具,因为它不计算CPU实际运行您的操作所需的时间,例如,如果线程根本没有运行,时间仍然会被计算在内。
相反,您必须使用特定于平台的API,比如用于POSIX兼容系统的pthread_getcpuclockid
(检查是否定义了_POSIX_THREAD_CPUTIME
),它计算特定线程实际花费的时间。
您可以查看我为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 */
}
https://stackoverflow.com/questions/56170540
复制相似问题