Время выполнения программы "5E-006"? - PullRequest
1 голос
/ 02 мая 2011
double SumOfSquare()()
{
    int i;
    double T3,total=0;

    for(i=0;i<200;i++) {
        clock_t start = clock();

        int n=100,sum=0;
        for(int i =1;i<=n;i++) {
            sum=sum+i*i;
        }


    clock_t end = clock();
    T3=double(end-start)/(double) CLOCKS_PER_SEC;
    total=total+T3;
    }

    T3=total/200;

    return T3;
 }


 int main()
 {

    double T3=SumOfSquare();
    cout<<T3<<endl;
    return 0;
 }

Этот код должен возвращать значение для времени выполнения этого кода, вместо этого он возвращает некое странное выражение, такое как "5e-006" вместо времени выполнения. Почему?

Ответы [ 6 ]

6 голосов
/ 02 мая 2011

5e-006 - это то же самое, что и 5 * 10^-6 или 0.000005. С чего вы взяли, что не время выполнения?

(5e-006 - число, записанное в записи E .)

4 голосов
/ 02 мая 2011

T3 является двойным, и его значение составляет 5 микросекунд, так что все в порядке.

2 голосов
/ 02 мая 2011

Как уже отмечали другие, вы получаете 5 микросекунд в результате, что кажется как минимум разумным временем.

Я бы, однако, вычислил времянемного по-другому.Я бы накапливал количество «тиков» для цикла: , затем конвертируем общее количество в секунды:

static const int iterations = 200;
clock_t total=0;
double seconds;

for(i=0;i<iterations;i++) {
    clock_t start = clock();

    int n=100,sum=0;
    for(int i =1;i<=n;i++) {
        sum=sum+i*i;
    }
    total += clock() - start;
}

return total/double(CLOCKS_PER_SEC*iterations);

Вместо деления с плавающей запятой и сложения с плавающей запятой при каждой итерации, этовыполняет целочисленное сложение на каждой итерации и одиночное деление с плавающей точкой в ​​самом конце.На слабом оборудовании это может быть быстрее.Что еще более важно, он, вероятно, будет более точным, почти независимо от аппаратного обеспечения - добавление длинного списка небольших чисел с плавающей запятой является одним из случаев, который часто приводит к существенной потере точности.

2 голосов
/ 02 мая 2011

5e-006 - это просто стандартная экспоненциальная запись для 5 * 10 -6 , т. Е. 0,000005. Это то же самое, что 6 мкс.

2 голосов
/ 02 мая 2011

Посмотрите на манипуляторы. Они используются для форматирования выходного потока, чтобы вы могли получить более осмысленный результат.

0 голосов
/ 02 мая 2011

Очевидный ответ заключается в том, что выполнение вашего кода занимает всего 5 микросекунд.Возможно, потому что вы никогда не используете sum, поэтому компилятор исключит любой код, используемый для изменения его значения (и, следовательно, внутреннего цикла).Ваше измерение, скорее всего, определяется гранулярностью clock.Вы также хотите измерить как можно больший период: я бы с подозрением отнесся к измерениям, если два вызова на clock составляют менее 5 минут на часть (но, конечно, я буду использовать гораздо более короткий интервалпри отладке программы :-)).Мое решение (и я не говорю, что оно идеально), как правило, заключалось в том, чтобы поместить измеряемый код в виртуальную функцию, в производный класс, с функцией в базовом классе, которая ничего не делает, что-то вроде:

class Base
{
    static int ourCount;
    static double ourTare;
    virtual void doRun();
public:
    double run();
    static void setCount( int count );
};

int Base::ourCount = 0;
double Base::ourTare = 0.0;

void Base::doRun() {}

double Base::run()
{
    clock_t start = clock();
    for ( int count = ourCount; count > 0; -- count )
        doRun();
    clock_t end = clock();
    return (static_cast<double>(end - start) / CLOCKS_PER_SEC - ourTare;
}

void Base::setCount( int count )
{
    ourCount = count;
    ourTare = 0.0;
    //  The following has been sufficient in the past.  If the
    //  compiler inlines Base::run, however, it could be
    //  insufficent.  (In my own code, Base::run is in a
    //  separate translation unit.)`
    ourTare = Base().run();
}

class Derived
{
    int d;
    virtual void doRun();
public:
};

void Derived::doRun()
{
    int sum = 0;
    for ( int i = 1; i <= 100; ++ i ) {
        sum += i * i;
    }
    d = sum;
}

Затем вы вызываете Base::setCount со счетом (для чего-то простого, например, бесполезного меньше, чем миллион), создаете экземпляр Derived и вызываете run, чтобы получить общее время в секундах.,Вы можете разделить его на количество, если вам нужно время на итерацию.

(Более легкомысленным ответом будет то, что программа выдает "5e-006", потому что компилятор не работает. Это недопустимый вывод для любой плавающей запятойзначение в C ++.)

...