Скорость печати () - PullRequest
       31

Скорость печати ()

1 голос
/ 25 февраля 2012

Я немного повеселился на языке C с библиотекой time.h , пытаясь измерить количество тактов некоторых основных функций, просто чтобы выяснить, насколько быстро они на самом делеявляются.Я использовал функцию clock () .В этом случае я измерял функцию printf () .

Посмотрите на мою программу:

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

void main()
{
    const int LIMIT = 2000;
    const int LOOP = 20;
    int results[LOOP];

    for(int i=0; i<LOOP; i++)
    {
        int j;
        clock_t time01 = clock();

        for(j=1; j<LIMIT; j++)
        {
            printf("a");
        }

        clock_t time02 = clock();
        results[i] = (int) (time02 - time01);
    }

    for(int i=0; i<LOOP; i++)
    {
        printf("\nCLOCK TIME: %d.", results[i]);        
    }
    getchar();
}

Программа просто в основном считает 20-кратное количество тактов2000 раз вызывал функцию printf ("a").

Странная вещь, которую я не понимаю, это результат. Я получаю большую часть времени, даже когда выполняю другие тесты, случайно две группы результатов:

CLOCK TIME: 31.
CLOCK TIME: 47.
CLOCK TIME: 47.
CLOCK TIME: 31.
CLOCK TIME: 47.
CLOCK TIME: 31.
CLOCK TIME: 47.
CLOCK TIME: 31.
CLOCK TIME: 47.
CLOCK TIME: 47.
CLOCK TIME: 31.
CLOCK TIME: 47.
CLOCK TIME: 31.
CLOCK TIME: 47.
CLOCK TIME: 47.
CLOCK TIME: 31.
CLOCK TIME: 47.
CLOCK TIME: 31.
CLOCK TIME: 47.
CLOCK TIME: 31.

Я не понимаю, как именно компилятор обрабатывает эту функцию.Я полагаю, что есть тест для символа % , но это не будет иметь значения.Похоже, компилятор что-то делает в памяти ... (?) Кто-нибудь знает точную основу компиляции этого кода или почему появляется такое различие, упомянутое выше?Или хоть какая-нибудь ссылка, которая мне поможет?

Спасибо.

Ответы [ 3 ]

2 голосов
/ 25 февраля 2012

Я могу вспомнить как минимум две возможные причины:

  1. Ваши часы имеют ограниченное разрешение.
  2. printf иногда будет сбрасывать свой буфер.
1 голос
/ 25 февраля 2012

Некоторые компиляторы (в частности, последние версии gcc в последних дистрибутивах Linux при оптимизации с помощью -O2) способны оптимизировать printf("a") в код, очень похожий на putchar( a )

Но большую часть времени проводит в ядре, делая системный вызов write.

0 голосов
/ 25 февраля 2012

Справочная страница clock сказала, что возвращает

приближение процессорного времени, используемого программой

Это приближение основано на известном Счетчике отметок времени . Как говорится в википедии:

Подсчитывает количество циклов с момента сброса

К сожалению, в настоящее время этот счетчик может варьироваться в зависимости от ядра.

Не обещается, что счетчики меток времени нескольких процессоров на одной материнской плате будут синхронизированы.

Так что будьте осторожны, чтобы заблокировать ваш код на определенном процессоре, в противном случае вы будете продолжать получать странные результаты. И поскольку вы, похоже, ищете точные результаты, вы можете использовать этот код вместо clock call:

  uint64_t rdtsc(void) {
    uint32_t lo, hi;
    __asm__ __volatile__ (      // serialize
    "xorl %%eax,%%eax \n        cpuid"
    ::: "%rax", "%rbx", "%rcx", "%rdx");
    /* We cannot use "=A", since this would use %rax on x86_64 and return only the lower 32bits of the TSC */
    __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
    return (uint64_t)hi << 32 | lo;
  }
...