0

我正在尝试测量以下代码的 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); 

但是当我增加 n 的值时,时间值是负的。代码打印 n = 500 的正确值,但它打印 n = 700 的负值 任何帮助将不胜感激。

这是完整的代码结构 -

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); 
}

这个函数 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);
4

4 回答 4

2

看起来像溢出使用unsigned long或更double适合diff

于 2012-05-10T05:24:02.590 回答
0

'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;

此代码可以简化,因为它不对“tv_sec”字段的符号做任何假设。大多数 Linux sys 头文件(和 glibc?)都提供宏来正确处理这种 timespec 算术,不是吗?

于 2012-05-10T05:52:50.457 回答
0

可能的问题原因之一是printf格式是长有符号整数值 ( %ld),但参数具有双精度类型。要解决此问题,必须更改%ld格式%lf字符串。

于 2012-05-10T06:04:07.797 回答
0

查看您的打印声明:

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

您传递的第二个参数是一个双精度参数,但您将此浮点值打印为一个长整数 (%ld)。我怀疑这是你问题的一半。

这可能会产生更好的结果:

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

我也同意 keety,您可能应该使用无符号类型,或者您可以通过保持毫秒单位而不是纳秒来完全避免溢出问题。这就是为什么我坚持使用 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);
于 2012-05-10T06:05:48.440 回答