切换时间单位时程序运行时长计算结果不一致问题排查
问题描述
我正在编写一个计算prefixSum(前缀和)和scan(扫描)的程序,希望以毫秒为单位统计运行时长,但测试时发现结果存在异常。
毫秒级计时函数
double executeFunction(double *arr, int size, void (*function)(double *, int)) { struct timespec start, end; clock_gettime(CLOCK_MONOTONIC, &start); function(arr, size); clock_gettime(CLOCK_MONOTONIC, &end); return (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1000000.0; }
秒级计时函数(仅最后一行不同)
double executeFunction(double *arr, int size, void (*function)(double *, int)) { struct timespec start, end; clock_gettime(CLOCK_MONOTONIC, &start); function(arr, size); clock_gettime(CLOCK_MONOTONIC, &end); return (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1000000000.0; }
打印时长代码
double cpu_time_used = executeFunction(arr, size, function); printf("Time taken: %f \n", cpu_time_used);
测试输出
毫秒级代码输出
Size: 1000000 Function: prefixSum Input file: /dev/null Time taken: 1.861000 ms Output file: /dev/null
秒级代码输出
Size: 1000000 Function: prefixSum Input file: /dev/null Time taken: 0.004642 seconds Output file: /dev/null
两者的时长结果相差甚远,不符合毫秒约为秒的1000倍的预期。尝试了不同的数组大小,但未发现明显规律,请问这一现象的原因是什么?
问题原因分析
你的毫秒级计时函数存在单位不统一的逻辑错误,导致计算结果完全不符合预期:
在毫秒级的executeFunction中,(end.tv_sec - start.tv_sec)得到的是时间差的秒数,而(end.tv_nsec - start.tv_nsec)/1000000.0得到的是时间差的毫秒数,直接把不同单位的值相加,相当于把“1秒”当成“1毫秒”来计算,结果自然偏差极大。
正确的毫秒级计算应该先把秒数部分转换为毫秒,再和纳秒转来的毫秒数相加:
return (end.tv_sec - start.tv_sec) * 1000.0 + (end.tv_nsec - start.tv_nsec) / 1000000.0;
另外,两次测试结果的数值差异(1.861ms vs 约4.642ms)是正常现象——程序运行时间会受CPU缓存命中情况、系统当前负载、进程调度等因素影响,每次执行的实际耗时都会有波动,但核心问题还是毫秒级计时的逻辑错误。
内容的提问来源于stack exchange,提问作者user24086036
相关产品推荐
相关产品推荐

