初始化与统一值速度测试

问题描述 投票:0回答:1

我正在观看一些视频,其中非常强调未初始化值的速度。然而,我看过另一个视频,指出初始化值实际上更快。我写了以下测试:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/time.h>

void a(int size) {
    int* a = malloc(sizeof(int) * size);
    memset(a, 0, sizeof(int) * size);
    for(int i = 0; i < size; i++) {
        a[i] = i;
    }
    free(a);
}
void b(int size) {
    int* a = malloc(sizeof(int) * size);
    for(int i = 0; i < size; i++) {
        a[i] = i;
    }
    free(a);
}
int test(void fun(int), int runs, int size) {
    int time = 0;
    for(int i = 0; i < runs; i++) {
        struct timeval beg = {0}, end = {0};
        gettimeofday(&beg, NULL);
        fun(size);
        gettimeofday(&end, NULL);
        int usec_diff = end.tv_usec - beg.tv_usec;
        if(usec_diff < 0) {
            time += 1000000;
        } else {
            time += usec_diff;
        }
    }
    return time;
}
int main() {
    int a_3 = test(&a, 100000, 1000);
    int b_3 = test(&b, 100000, 1000);
    printf("b/a ^3: %f\n", (float)b_3 / a_3);
    int a_4 = test(&a, 100000, 10000);
    int b_4 = test(&b, 100000, 10000);
    printf("b/a ^4: %f\n", (float)b_4 / a_4);
    int a_5 = test(&a, 100000, 100000);
    int b_5 = test(&b, 100000, 100000);
    printf("b/a ^5: %f\n", (float)b_5 / a_5);
}

我只是想知道这是否是一个好的测试,以及是否相信结果。我得到以下输出:

eck@eck:~/src/test$ ./main
b/a ^3: 2.764046
b/a ^4: 0.989866
b/a ^5: 0.990233

这似乎很合理,但我想问一下,因为我以前从未写过这样的测试。

编辑:我记得您可以查看生成的程序集,我发现使用 -O1,两个函数都会生成相同的程序集。但是,我不确定您是否可以在更复杂的场景中执行此操作,并且仍然希望澄清初始化与未初始化的事情。

c testing initialization
1个回答
0
投票

您的测量方法是错误的。

  • 您测量的东西非常随机。
  • 如果使用启用优化的函数进行编译,
    a
    b
    将被优化为返回函数:
                  b:
0000000000401dd0:   endbr64 
0000000000401dd4:   ret     
                  a:
0000000000401de0:   endbr64 
0000000000401de4:   ret     

即使函数被简化为简单的

ret
语句,你的代码也会显示无意义的结果。

b/a ^3: 1.580129
b/a ^4: 0.376331
b/a ^5: 0.378220

b/a ^3: 1.003253
b/a ^4: 1.079337
b/a ^5: 0.243827

所以你无法通过这种方式测量执行时间。

您还需要修改函数,使其不被编译器优化:

int *a(size_t size) {
    int* a = malloc(sizeof(int) * size);
    memset(a, 0, sizeof(int) * size);
    for(size_t i = 0; i < size; i++) {
        a[i] = i;
    }
    return a;
}
int *b(size_t size) {
    int* a = malloc(sizeof(int) * size);
    for(size_t i = 0; i < size; i++) {
        a[i] = i;
    }
    return a;
}
double test(int *fun(size_t), size_t runs, size_t size) {
    clock_t begin = clock();
    int *a;
    for(size_t i = 0; i < runs; i++) {
        a = fun(size);
        free(a);
    }
    clock_t end = clock();
    double time = (double)(end - begin) / CLOCKS_PER_SEC;
    return time;
}
int main() {
    double a_3 = test(&a, 100000ULL, 1000);
    double b_3 = test(&b, 100000ULL, 1000);
    printf("b/a ^3: %f\n", b_3 / a_3);
    double a_4 = test(&a, 100000ULL, 10000);
    double b_4 = test(&b, 100000ULL, 10000);
    printf("b/a ^4: %f\n", b_4 / a_4);
    double a_5 = test(&a, 100000ULL, 100000);
    double b_5 = test(&b, 100000ULL, 100000);
    printf("b/a ^5: %f\n", b_5 / a_5);
}

结果:

b/a ^3: 0.760627
b/a ^4: 0.772483
b/a ^5: 0.732345

结论:

将内存归零会增加显着的开销。

© www.soinside.com 2019 - 2024. All rights reserved.