C - серия операторов if против других, если измерение времени - PullRequest
0 голосов
/ 25 апреля 2018

Заранее прошу прощения, если моей терминологии не хватает.Я написал код, чтобы продемонстрировать неэффективность ряда операторов if против операторов else / if.И результаты не имеют никакого смысла для меня.

Это простой алгоритм, который проходит через массив (100000000 элементов) и подсчитывает вхождения элементов, будучи 1,2,3,4,5 или иначе.

clock_t time1;
time1 = clock();
    for (int i=1; i<=n; i++)
    {
        if (arr[i]==1)
            p1++;
        if (arr[i]==2)
            p2++;
        if (arr[i]==3)
            p3++;
        if (arr[i]==4)
            p4++;
        if (arr[i]==5)
            p5++;
        if (!(arr[i]>=1 && arr[i]<=5))
            j++;
    }
time1 = clock() - time1;

printf("count of 1s:\t %d\n",p1);
printf("count of 2s:\t %d\n",p2);
printf("count of 3s:\t %d\n",p3);
printf("count of 4s:\t %d\n",p4);
printf("count of 5s:\t %d\n",p5);
printf("count of errors:\t %d\n",j);
printf("\n ---  counting took: %.10f ms---\n",((double)(time1)/CLOCKS_PER_SEC)*1000);

, а затем то же самое, но с другим, если

clock_t time2;
time2 = clock();
    for (int i=1; i<=n; i++)
    {
        if (arr[i]==1)
            p1++;
        else if (arr[i]==2)
            p2++;
        else if (arr[i]==3)
            p3++;
        else if (arr[i]==4)
            p4++;
        else if (arr[i]==5)
            p5++;
        else j++;
    }
time2 = clock() - time2;

, как и ожидалось, если дан массив случайных значений от 1 до 5, в противном случае, если скорость примерно в два раза, НО (здесьвозникает путаница) когда ему дают массив из тысячи единиц, я ожидаю, что ряд if будет занимать одинаковое количество времени до н.э., он должен проверять каждое условие, даже если первое уже выполнено - но это занимает ПОЛОВИНУ времени и когда ядать ему массив только 5 с, это также быстрее.

Кто-нибудь может объяснить, как это может быть быстрее, пожалуйста?- Спасибо: / (когда я даю ему значения от 4 до 5, на самом деле это занимает примерно то же время, что и значения от 1 до 5)

(вот результаты всего этого [не обращайте внимания на чешский язык, пожалуйста])

Редактировать

Время показанное на картинке:

Code 1 - random input: 2451 ms
Code 2 - random input: 2401 ms

Code 1 - all-one input: 932 ms
Code 2 - all-one input: 573 ms

Code 1 - all-five input: 923 ms
Code 2 - all-five input: 697 ms

1 Ответ

0 голосов
/ 25 апреля 2018

Современные процессоры очень сложные звери.

Я полагаю, что вы больше тестируете предиктор ветвления ЦП, чем что-либо еще: если вы заполняете массив случайными числами из диапазона 1 ... 5, предикторы ветвления довольно часто будут угадывать, когда выполняется любой из if .

Если вы заполните массив константами, предикторы будут правильными на 100%.

т.е. при рандомизированном вводе число вычисленных if s действительно имеет значение, так как значительное их количество вызывает остановку конвейера ЦП.

При постоянном вводе число выполненных if s более или менее пренебрежимо мало, и нет остановок конвейера. Все, что имеет значение, это внутренние компоненты процессора, а также то, насколько хорошо ваш компилятор способен оптимизировать ваш код. Умный компилятор может эффективно заменить один из двух или оба ваших примера на оператор switch, поэтому, не глядя на сгенерированные инструкции, мы можем просто предположить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...