gettimeofday函数精度是多少?测试调用耗时输出0微秒是什么原因?
测试代码存在的问题
- 整数除法截断误差:现代x86系统中
gettimeofday通过vdso机制实现,不需要陷入内核,单次调用开销仅十几到几十纳秒,远小于1微秒。10万次调用总耗时通常在1~2微秒量级,你使用long类型整数除法计算平均值,小于1的部分会被直接截断为0,自然得到平均耗时为0的错误结果。 - 耗时计算逻辑错误:你直接用两次采样的
tv_usec字段相减计算差值,没有考虑跨秒边界的情况:如果测试过程中刚好跨过整数秒,tv_usec会从999999跳转到0,直接相减会得到负数,结果完全失真。 - 测试引入额外开销:你在栈上申请了10万个
struct timeval结构的数组,每次调用gettimeofday后都要写入数组,额外的内存写入操作会干扰实际的调用开销测试结果。 - 编译器优化风险:如果开启较高编译优化等级,编译器可能识别到你后续没有使用
current_time数组的中间值,直接优化掉部分gettimeofday调用,导致测试结果不符合预期。
对作者表述的理解
作者提到的「gettimeofday()返回微秒级时间但不代表精度达到微秒级」是通用场景下的表述,针对不同硬件/系统存在差异:
- 老式系统使用周期触发的PIT时钟,时钟tick间隔通常为1ms~10ms,
gettimeofday只会在每次tick时更新时间值,精度就是tick间隔,远低于微秒。 - 现代x86系统默认使用TSC作为时钟源,支持tickless调度,
gettimeofday的实际精度可以达到纳秒级,不存在精度不足的问题。
修正后的测试代码
#include <stdio.h> #include <sys/time.h> // 加大循环次数,降低测量误差 #define MAX_TIMES 10000000 int main() { struct timeval start, end; long long total_us, avg_ns; int i; // 预热cache,避免首次调用开销影响结果 gettimeofday(&start, NULL); gettimeofday(&start, NULL); for (i = 0; i < MAX_TIMES; ++i) { struct timeval tmp; gettimeofday(&tmp, NULL); // 内存屏障+使用tmp值,防止编译器优化掉gettimeofday调用 asm volatile("" : : "r"(tmp.tv_usec) : "memory"); } gettimeofday(&end, NULL); // 正确计算总耗时 total_us = (end.tv_sec - start.tv_sec) * 1000000LL + (end.tv_usec - start.tv_usec); avg_ns = (total_us * 1000LL) / MAX_TIMES; printf("总耗时:%lld us\n单次调用平均耗时:%lld ns\n", total_us, avg_ns); return 0; }
编译运行建议:使用gcc -O2 test.c -o test编译后运行,正常结果为单次调用平均耗时在10~50ns区间。
内容的提问来源于stack exchange,提问作者shino
相关产品推荐
相关产品推荐

