首页 > 解决方案 > 相同函数消耗的时钟数会根据其执行顺序而发生巨大变化

问题描述

我试图测量 c 中顺序搜索所消耗的时钟周期。

int seqsearch(int arr[], int n, int val){
    for(int i = 0; i < n ; i++){
        if(arr[i] == val)
            return i;
    }
    return -1;
}

void main(){
    int arr[20000];
    for(int i = 0; i < 20000; i++){
        arr[i] = i;
    }
    int search = 17777;
    double time;
    clock_t start, end, consumed;
    start = clock();
    printf("\nSearch for %d :%d\n", search, seqsearch(arr, 20000, search));
    end = clock();
    consumed = end - start;
    printf("\nNo. of clocks consumed = %ld\n", consumed);
    time = (end - start) / CLOCKS_PER_SEC;
    printf("\nRuntime = %lf\n", time);
    start= clock();
    printf("\nSearch for %d :%d\n", search, seqsearch(arr, 20000, search));
    end = clock();
    consumed = end - start;
    printf("\nNo.of clocks consumed:%ld\n", consumed);
    time = (end - start) / CLOCKS_PER_SEC;
    printf("\nRuntime:%lf\n", time);
}

输出:

$ ./a.out

Search for 17777 :17777

No. of clocks consumed = 339

Runtime = 0.000000

Search for 17777 :17777

No.of clocks consumed:177

Runtime:0.000000

每次我执行它时,第二次执行所消耗的公鸡周期都比第一次所消耗的要少得多。如果我几乎同时执行两次相同的功能,两次执行不应该花费几乎相同的时钟周期。

标签: clinux

解决方案


我能够重现您的原始结果(稍作调整以正确打印时间):https ://ideone.com/ilQcmU 。

然后我制作了一个没有计时的版本printf,因为这很慢并且与您计时的事情无关:https ://ideone.com/gVC01c 。

...
int result;
start = clock();
result = seqsearch(arr,20000,search);
end = clock();
printf("\nSearch for %d :%d\n",search, result);
consumed = end - start;
printf("No. of clocks consumed = %ld\n",consumed);
time = (double)consumed/CLOCKS_PER_SEC;
printf("Runtime = %lf\n",time);
...

第二个打印输出以相同的方式修改。结果表明,这可能是你的罪魁祸首:

Search for 17777 :17777
No. of clocks consumed = 10
Runtime = 0.000010

Search for 17777 :17777
No.of clocks consumed:9
Runtime:0.000009

然后我将整个事情陷入一个循环,以检查缓存是否有明显的效果:https ://ideone.com/xYsL5x 。

...
int result, i;
for(i = 0; i < 10; i++) {
    start = clock();
    result = seqsearch(arr,20000,search);
    end = clock();
    printf("\nSearch for %d :%d\n",search, result);
    consumed = end - start;
    printf("No. of clocks consumed = %ld\n",consumed);
    time = (double)consumed/CLOCKS_PER_SEC;
    printf("Runtime = %lf\n",time);
}
...

看起来缓存在这里并没有错,但是对于这种时间分辨率,很难确定。即使它确实有效果,它显然也不重要。

为了完整起见,我将打印输出放回循环中的时间:https ://ideone.com/HnYkVd 。

...
int i;
for(i = 0; i < 10; i++) {
    start = clock();
    printf("\nSearch for %d :%d\n",search, seqsearch(arr,20000,search));
    end = clock();
...

在这里,有一个清晰可见的启动效果。我认为它不一定是缓存。我认为打印机制更有可能是缓冲区重新分配而不是其他任何事情。


推荐阅读