简体   繁体   English

为什么CPU时间是负的

[英]Why CPU time is negative

I am trying to measure the CPU time of following code - struct timespec time1, time2, temp_time; 我正在尝试测量以下代码的CPU时间 - struct timespec time1,time2,temp_time;

          clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);

          long diff = 0;

          for(int y=0; y<n; y++) {

                for(int x=0; x<n; x++) {

                float v = 0.0f;

                 for(int i=0; i<n; i++)

                     v += a[y * n + i] * b[i * n + x];

                       c[y * n + x] = v;

                   }

            }
        clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);

        temp_time.tv_sec = time2.tv_sec - time1.tv_sec;

        temp_time.tv_nsec = time2.tv_nsec - time1.tv_nsec;

        diff = temp_time.tv_sec * 1000000000 + temp_time.tv_nsec; 

       printf("finished calculations using CPU in %ld ms \n", (double) diff/1000000); 

But the time value is negative when i increase the value of n. 但是当我增加n的值时,时间值是负的。 Code prints correct value for n = 500 but it prints negative value for n = 700 Any help would be appreciated. 代码打印n = 500的正确值,但它打印负值n = 700任何帮助将不胜感激。

Here is the full code structure - 这是完整的代码结构 -

void run(float A[], float B[], float C[], int nelements){
    struct timespec time1, time2, temp_time;

          clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);

          long diff = 0;

          for(int y=0; y<nelements; y++) {

                for(int x=0; x<nelements; x++) {

                float v = 0.0f;

                 for(int i=0; i<nelements; i++)

                     v += A[y * nelements + i] * B[i * nelements + x];

                       C[y * nelements + x] = v;

                   }

            }
        clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);

        temp_time.tv_sec = time2.tv_sec - time1.tv_sec;

        temp_time.tv_nsec = time2.tv_nsec - time1.tv_nsec;

        diff = temp_time.tv_sec * 1000000000 + temp_time.tv_nsec; 

       printf("finished calculations using CPU in %ld ms \n"(double) diff/1000000); 
}

This function abovr is called from different fil as follows: 这个函数abovr从不同的fil调用如下:

SIZE = 500;

a = (float*)malloc(SIZE * SIZE * sizeof(float));

b = (float*)malloc(SIZE * SIZE * sizeof(float));

c = (float*)malloc(SIZE * SIZE * sizeof(float));

//initialize a &b
run(&a[SIZE],&b[SIZE],&c[SIZE],SIZE);

看起来像溢出使用unsigned long或更好的double用于diff

The 'tv_nsec' field should never exceed 10^9 (1000000000), for obvious reasons: 'tv_nsec'字段不应超过10 ^ 9(1000000000),原因显而易见:

if (time1.tv_nsec < time2.tv_nsec)
{
    int adj = (time2.tv_nsec - time1.tv_nsec) / (1000000000) + 1;

    time2.tv_nsec -= (1000000000) * adj;
    time2.tv_sec += adj;
}

if (time1.tv_nsec - time2.tv_nsec > (1000000000))
{
    int adj = (time1.tv_nsec - time2.tv_nsec) / (1000000000);

    time2.tv_nsec += (1000000000) * adj;
    time2.tv_sec -= adj;
}

temp_time.tv_sec = time1.tv_sec - time2.tv_sec;
temp_time.tv_nsec = time1.tv_nsec - time2.tv_nsec;

diff = temp_time.tv_sec * (1000000000) + temp_time.tv_nsec;

This code could be simplified, as it makes no assumptions about the sign of the 'tv_sec' field. 这段代码可以简化,因为它不会对'tv_sec'字段的符号做出任何假设。 Most Linux sys headers (and glibc?) provide macros to handle this sort of timespec arithmetic correctly don't they? 大多数Linux系统头文件(和glibc?)提供宏来正确处理这种timespec算法不是吗?

One of possible problem causes is that the printf format is for a long signed integer value ( %ld ), but the parameter has the double type. 可能的问题原因之一是printf格式用于长有符号整数值( %ld ),但参数具有double类型。 To fix the problem is necessary change %ld to %lf in the format string. 要解决此问题,必须将格式字符串中的%ld更改为%lf

Look at your print statement: 看看你的印刷声明:

printf("finished calculations using CPU in %ld ms \n", (double) diff/1000000);

The second parameter you pass is a double, but you are printing out this floating point value as a long (%ld). 您传递的第二个参数是double,但您将此浮点值打印为long(%ld)。 I suspect that's half your problem. 我怀疑这是你问题的一半。

This may generate better results: 这可能会产生更好的结果:

printf("finished calculations using CPU in %f ms \n", diff/1000000.0);

I also agree with keety, you likely should be using unsigned types Or you could possibly avoid the overflow issues altogether by staying in millisecond units instead of nanoseconds. 我也同意keety,你可能应该使用无符号类型或者你可以通过保持毫秒单位而不是纳秒来完全避免溢出问题。 Here's why I stick with 64-bit unsigned integers and just stay in the millisecond realm. 这就是为什么我坚持使用64位无符号整数并保持在毫秒范围内的原因。

unsigned long long diffMilliseconds;

diffMilliseconds = (time2.tv_sec * 1000LL + time2.tv_nsec/1000000) - (time1.tv_sec * 1000LL + time1.tv_nsec/1000000);

printf("finished calculations using CPU in %llu ms \n", diffMilliseconds);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM