【问题标题】:Unexpected runtime of loop意外的循环运行时间
【发布时间】:2020-02-25 09:12:05
【问题描述】:

我正在编写一个侧信道攻击演示。我期望一个简单的逐个字符检查并提前返回,以对第一个不正确的字符采取线性比例的时间。例如,如果我有密码passwordqassword(第一个字母错误)和passwore(最后一个字母错误)的输入,我预计qassword 的比较时间少于passwore(因为它提前退出,在第一个错误的字母上)。

有问题的循环是:

for (int i = 0; i < 26; i++) {
    if (a[i] != in[i]) {
        return 1;
    }
}
return 1;

我已禁用 -O0 的优化。

完整代码的输出为:

Diff(9326)
Diff(2)
Diff(1)
Diff(9292)

这让我感到惊讶,因为第一种情况是检查所有字母(好吧,应该花费最长的时间),第二种情况是检查除最后​​一个字母之外的所有字母(应该与第一种情况花费大约相同的时间? ) 并且最后一种情况应该只检查第一个字母(好的,花费最少的时间)。

我的问题是,为什么完全正确的情况需要这么长时间,而对于所有其他情况(即使错误的字母在中间)又如此之快?

完整代码为(Try It Online):

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

int check(char* in) {
    const char* a = "abcdefghijklmnopqrstuvwxyz";

    for (int j = 0; j < 100000; j++) {
        for (int i = 0; i < 26; i++) {
            if (a[i] != in[i]) {
                return 1;
            }
        }
    }

    return 1;
}

int main() {
    clock_t start;
    clock_t diff;

    // All correct
    start = clock();
    check("abcdefghijklmnopqrstuvwxyz");
    diff = clock() - start;

    printf("Diff(%ld)\n", diff);

    // Last letter wrong
    start = clock();
    check("abcdefghijklmnopqrstuvwxya");
    diff = clock() - start;

    printf("Diff(%ld)\n", diff);

    // First letter wrong
    start = clock();
    check("zbcdefghijklmnopqrstuvwxyz");
    diff = clock() - start;

    printf("Diff(%ld)\n", diff);

    // Check if cache issue (same as case 1)
    start = clock();
    check("abcdefghijklmnopqrstuvwxyz");
    diff = clock() - start;

    printf("Diff(%ld)\n", diff);
}

【问题讨论】:

    标签: c performance for-loop gcc runtime


    【解决方案1】:

    问题出在您的代码中。如果所有字符都匹配,那么它将检查 100000 次。但是,如果任何一个字符不匹配,那么您将在第一次迭代本身中从循环中返回。因此,当所有字符都不匹配时,时间差很小。

    在 if 块中放置一个 break 语句而不是 return

            for (int j = 0; j < 100000; j++) {
                     for (int i = 0; i < 26; i++) {
                         if (a[i] != in[i]) {
                             break;
                         }
                      }
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多