使用clock_gettime()每次执行获得的运行时间不一样

该博客探讨了在使用`clock_gettime(CLOCK_MONOTONIC)`测量程序执行时间时遇到结果不一致的问题。作者建议通过多次测量并取平均值来减少干扰因素,如多任务调度导致的时间暂停。他们提供了一个示例代码,通过增加测试次数来得到更准确的结果,并强调了系统调度对测量结果的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

struct timespec start, end; //nanoseconds
double time_gen;
time_gen = 0.0;


clock_gettime(CLOCK_MONOTONIC, &start);

XX_gen(key);

clock_gettime(CLOCK_MONOTONIC, &end);

time_gen += (double) (1000 * (end.tv_sec - start.tv_sec)) + (double) (end.tv_nsec - start.tv_nsec)/1000000;

printf("\nTime for XX_gen is %8.6f mSec. \n",  time_gen);

问题描述:

But every time I run the program I am getting different results. What am I doing wrong?

解决方案:

When you say "different results", can you please be more specific? What ranges do you get? And since you use the wall clock, you are aware of that Linux is a multi-tasking operating kernel, that might pause your process and let other processes work, and you have no real control over how long or how many times your process might be paused, and that of course will skew your results. To get a better result, do the operation thousands (or even millions) of times, and calculate the average time. 

– Some programmer dude

 Sep 8 '15 at 

I've used this method of measuring before and you are doing nothing wrong. Even when you have your scheduling right your output will always fluctuate.

The overhead I used to have was around 250 microseconds if the thread didn't get interrupted by another process, but I suppose this is very dependent on the CPU power as well.

For the overhead: Try measuring a few hundreds/thousands times with an empty body, check the lowest (least interrupted) output to examine the overhead.

For your results: Try the same and take again the lowest value, this way you can approach the actual value you are looking for. Keep in mind that a single read and write might be not-measurable fast.

—— answered Sep 8 '15 at 14:12

koldewb

#define  TESTNUM 1000000

struct timespec start, end; //nanoseconds
double time_gen;
time_gen = 0.0;

clock_gettime(CLOCK_MONOTONIC, &start);
for (int i = 0; i < TESTNUM; i++)
{
    XX_gen(key);
}
clock_gettime(CLOCK_MONOTONIC, &end);

time_gen += (double) (1000 * (end.tv_sec - start.tv_sec)) + (double) (end.tv_nsec - start.tv_nsec)/1000000;

printf("\nTime for XX_gen is %8.6f mSec. \n",  time_gen/TESTNUM);

解决方案来源【版权侵删】:

c - Getting Inconsistent results with clock_gettime() - Stack Overflow

<think>好的,我现在需要解释srand(time(NULL))的原理。首先,用户可能想知道这个函数在C或C++中的作用,特别是生成随机数相关的。srand是用来初始化随机数生成器的,而time(NULL)可能是用来获取当前时间作为种子。 我需要先确认srand和rand函数的关系。srand设置种子后,rand会根据这个种子生成伪随机数序列。种子相同的话,每次生成的序列都一样,所以通常用时间作为种子,因为时间每秒都在变,这样每次运行程序得到的随机数同。 time(NULL)返回的是当前的时间戳,也就是从1970年1月1日到现在经过的秒数。用这个值作为种子,可以保证每次程序启动时种子同,从而产生同的随机数序列。 可能要注意的是,如果程序在短时间内多次调用srand(time(NULL)),比如在同一秒内多次初始化,那么种子可能相同,导致随机数重复。这在某些情况下可能是个问题,需要避免频繁重置种子。 另外,需要提到的是,虽然用时间作为种子是常见做法,但并是真正的随机,还是伪随机。对于更高安全性的需求,可能需要其他方法,比如使用硬件随机数生成器。 我应该分步骤解释:srand的作用,time(NULL)的作用,两者结合的原理,以及潜在的问题和使用注意事项。确保用户明白为什么这样用,以及可能的限制。同时给出一个简单的代码示例,展示典型用法,比如生成随机数前先srand初始化。</think>在C/C++编程中,`srand(time(NULL))` 是用于初始化伪随机数生成器的经典写法,其工作原理可以拆解为两个核心部分: --- ### 一、`time(NULL)` 的作用 - **获取时间戳**:调用 `time(NULL)` 会返回从 **1970年1月1日00:00:00 UTC**(即UNIX纪元)到当前时刻经过的秒数(类型为`time_t`) - **动态值特性**:因为时间每时每刻都在变化,所以每次运行程序时 `time(NULL)` 的返回值都会同 - **示例值**: ```c time_t now = time(NULL); // 假设当前时间为2023年10月1日 printf("%ld", now); // 输出类似1696147200(具体值随时间变化) ``` --- ### 二、`srand()` 的作用 - **种子初始化**:`srand(unsigned int seed)` 函数用于设置伪随机数生成器的种子值 - **种子决定序列**:给定相同种子时,`rand()` 函数生成的随机数序列完全一致 ```c srand(123); // 固定种子 printf("%d", rand() % 100); // 每次输出相同的"随机"数 ``` --- ### 三、组合原理 通过将 **动态变化的时间戳** 作为种子,可以实现: 1. **避免重复序列**:每次程序运行时种子同 → 生成同的随机数序列 2. **简化初始化**:无需手动管理种子值,自动随时间变化 --- ### 四、典型使用场景 ```c #include <stdio.h> #include <stdlib.h> #include <time.h> int main() { srand(time(NULL)); // 初始化随机种子 for(int i=0; i<5; i++) { printf("%d ", rand() % 100); // 生成0-99的随机数 } return 0; } ``` 每次运行输出同结果: ``` 83 77 15 93 35 74 52 41 89 52 ``` --- ### 五、注意事项 | 场景 | 问题 | 解决方案 | |------|------|----------| | 高频调用 | 同一秒内多次调用会导致种子相同 | 确保整个程序只初始化一次 | | 安全性 | 时间种子可预测,适用于加密场景 | 改用加密安全库(如OpenSSL) | | 精度足 | 秒级时间戳粒度较粗 | 使用更高精度时钟(如`clock_gettime`) | --- ### 六、进阶优化 对于需要更高质量的随机数,可以组合多个熵源: ```c #include <unistd.h> srand(time(NULL) ^ getpid()); // 结合进程ID增加随机性 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值