Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 测量代码块执行时间N倍的问题_C_Time_Clock_Performance - Fatal编程技术网

C 测量代码块执行时间N倍的问题

C 测量代码块执行时间N倍的问题,c,time,clock,performance,C,Time,Clock,Performance,编辑:在写了这篇解释每一个细节的长文章后,我发现了我的问题。。。如果有人能给我一个很好的答案,说明我做错了什么,以及如何以秒为单位获得执行时间(使用小数点后5位左右的浮点),我会将其标记为已接受。提示:问题在于我如何解释clock_gettime()手册页 嗨 假设我有一个名为myOperation的函数,我需要它来测量的执行时间。为了衡量它,我使用了一条评论中推荐的clock\u gettime() 我的老师建议我们测量它N次,这样我们就可以得到最终报告的平均值、标准偏差和中位数。他还建议我们

编辑:在写了这篇解释每一个细节的长文章后,我发现了我的问题。。。如果有人能给我一个很好的答案,说明我做错了什么,以及如何以秒为单位获得执行时间(使用小数点后5位左右的浮点),我会将其标记为已接受。提示:问题在于我如何解释clock_gettime()手册页

假设我有一个名为
myOperation
的函数,我需要它来测量的执行时间。为了衡量它,我使用了一条评论中推荐的
clock\u gettime()

我的老师建议我们测量它
N
次,这样我们就可以得到最终报告的平均值、标准偏差和中位数。他还建议我们执行
myOperation
M
次,而不是只执行一次。如果
myOperation
是一个非常快速的操作,那么测量
M
次可以让我们了解它所需要的“实时性”;原因正在使用的时钟可能没有测量此类操作所需的精度。因此,执行
myOperation
仅一次或
M
次实际上取决于操作本身是否需要足够长的时间才能达到我们使用的时钟精度

我在处理
m
次执行时遇到问题。增加
M
会减少(很多)最终平均值。这对我来说毫无意义。就像这样,从A点到B点平均需要3到5秒的时间,然后从A点到B点再回到A点5次(也就是说10次,因为A到B点和B到A点相同),然后你测量。除以10,你得到的平均值应该是从A点到B点的平均值,也就是3到5秒

这就是我想要我的代码做的,但它不起作用。如果我不断增加从A到B再回到A的次数,平均每次都会越来越低,这对我来说毫无意义

理论够了,下面是我的代码:

#include <stdio.h>
#include <time.h>

#define MEASUREMENTS 1
#define OPERATIONS   1

typedef struct timespec TimeClock;

TimeClock diffTimeClock(TimeClock start, TimeClock end) {
    TimeClock aux;

    if((end.tv_nsec - start.tv_nsec) < 0) {
        aux.tv_sec = end.tv_sec - start.tv_sec - 1;
        aux.tv_nsec = 1E9 + end.tv_nsec - start.tv_nsec;
    } else {
        aux.tv_sec = end.tv_sec - start.tv_sec;
        aux.tv_nsec = end.tv_nsec - start.tv_nsec;
    }

    return aux;
}

int main(void) {
    TimeClock sTime, eTime, dTime;
    int i, j;

    for(i = 0; i < MEASUREMENTS; i++) {
        printf(" » MEASURE %02d\n", i+1);

        clock_gettime(CLOCK_REALTIME, &sTime);

        for(j = 0; j < OPERATIONS; j++) {
            myOperation();
        }

        clock_gettime(CLOCK_REALTIME, &eTime);

        dTime = diffTimeClock(sTime, eTime);

        printf("   - NSEC (TOTAL): %ld\n", dTime.tv_nsec);
        printf("   - NSEC (OP): %ld\n\n", dTime.tv_nsec / OPERATIONS);
    }

    return 0;
}
对于
OPERATIONS=100
,结果如下:

 » MEASURE 01
   - NSEC (TOTAL): 27456580
   - NSEC (OP): 27456580
 » MEASURE 01
   - NSEC (TOTAL): 218929736
   - NSEC (OP): 2189297
 » MEASURE 01
   - NSEC (TOTAL): 862834890
   - NSEC (OP): 862834
 » MEASURE 01
   - NSEC (TOTAL): 574133641
   - NSEC (OP): 57413
对于
OPERATIONS=1000
,结果如下:

 » MEASURE 01
   - NSEC (TOTAL): 27456580
   - NSEC (OP): 27456580
 » MEASURE 01
   - NSEC (TOTAL): 218929736
   - NSEC (OP): 2189297
 » MEASURE 01
   - NSEC (TOTAL): 862834890
   - NSEC (OP): 862834
 » MEASURE 01
   - NSEC (TOTAL): 574133641
   - NSEC (OP): 57413
对于
OPERATIONS=10000
,结果如下:

 » MEASURE 01
   - NSEC (TOTAL): 27456580
   - NSEC (OP): 27456580
 » MEASURE 01
   - NSEC (TOTAL): 218929736
   - NSEC (OP): 2189297
 » MEASURE 01
   - NSEC (TOTAL): 862834890
   - NSEC (OP): 862834
 » MEASURE 01
   - NSEC (TOTAL): 574133641
   - NSEC (OP): 57413
现在,我不是一个数学天才,事实上离它很远,但这对我来说毫无意义。我已经和一个和我一起做这个项目的朋友谈过了,他也不理解其中的区别。我不明白当我增加
操作时,为什么值越来越低。无论我执行了多少次,操作本身都应该花费相同的时间(当然,平均而言,不是完全相同的时间)

你可以告诉我,这实际上取决于操作本身,数据被读取,一些数据可能已经在缓存和bla-bla中,但我认为这不是问题所在。在我的例子中,
myOperation
从一个CSV文件中读取5000行文本,用
分隔值并将这些值插入到数据结构中。对于每次迭代,我都会破坏数据结构并再次初始化它

现在我想起来了,我也认为用
clock\u gettime()
测量时间有问题,也许我用得不对。我的意思是,看最后一个例子,其中
OPERATIONS=10000
。总时间为574133641ns,约为0,5s;这是不可能的,因为我无法忍受看着屏幕等待并去吃东西,所以花了几分钟时间。

我通常使用time()函数来实现这一点。它显示了墙上的时钟时间,但这才是我最终真正关心的

性能测试的一个难题是操作系统可能缓存与文件系统相关的操作。因此,第二次(以及以后的)运行可能比第一次运行快得多。您通常需要测试may操作并平均结果,以便对所做的任何更改的结果有一个良好的感觉。有太多的变量可以帮助您滤除噪音。

我通常使用time()函数来实现这一点。它显示了墙上的时钟时间,但这才是我最终真正关心的


性能测试的一个难题是操作系统可能缓存与文件系统相关的操作。因此,第二次(以及以后的)运行可能比第一次运行快得多。您通常需要测试may操作并平均结果,以便对所做的任何更改的结果有一个良好的感觉。有太多的变量可以帮助您过滤噪音。

时钟类型有两个字段,一个用于秒,一个用于纳秒。将nanosec字段除以操作数是没有意义的。您需要划分总时间。

时钟类型有两个字段,一个表示秒,一个表示纳秒。将nanosec字段除以操作数是没有意义的。您需要划分总时间。

如果您使用的是POSIX系统,其中有gettimeofday()函数,您可以使用类似的方法以微秒为单位获取当前时间:

long long timeInMicroseconds(void) {
    struct timeval tv;

    gettimeofday(&tv,NULL);
    return (((long long)tv.tv_sec)*1000000)+tv.tv_usec;
}
这非常方便的原因是,为了计算函数花费了多少时间,您只需执行以下操作:

long long start = timeInMicroseconds();
... do your task N times ...
printf("Total microseconds: %lld", timeInMicroseconds()-start);

所以你不需要处理两个整数,一个是秒,一个是微秒。添加和减去时间将以一种明显的方式工作。

如果您使用的是POSIX系统,其中有gettimeofday()函数,您可以使用类似的方法以微秒为单位获取当前时间:

long long timeInMicroseconds(void) {
    struct timeval tv;

    gettimeofday(&tv,NULL);
    return (((long long)tv.tv_sec)*1000000)+tv.tv_usec;
}
这非常方便的原因是,为了计算函数花费了多少时间,您只需执行以下操作:

long long start = timeInMicroseconds();
... do your task N times ...
printf("Total microseconds: %lld", timeInMicroseconds()-start);

所以你不需要处理两个整数,一个是秒,一个是微秒。添加和减去时间将以一种明显的方式工作。

您只需更改
diffTimeClock()
函数,以
双精度返回秒数差