Глядя на сборку, полученную из g++ -O3 -S
, становится очевидным, что циклы и все ваши вычисления с плавающей запятой (кроме тех, которые связаны со временем) были оптимизированы:
.section .text.startup,"ax",@progbits
.p2align 4,,15
.globl main
.type main, @function
main:
.LFB970:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
pushq %rbx
.cfi_def_cfa_offset 24
.cfi_offset 3, -24
subq $24, %rsp
.cfi_def_cfa_offset 48
call clock
movq %rax, %rbx
call clock
movq %rax, %rbp
movl $.LC0, %esi
movl std::cout, %edi
subq %rbx, %rbp
call std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
Видите два звонка на clock
, один за другим? И перед этим, только некоторые инструкции по обслуживанию стека. Да, эти петли полностью исчезли.
Вы используете f_answer
или d_answer
только для распечатки ответа, который может быть тривиально вычислен во время компиляции, и компилятор может это увидеть. Нет смысла даже иметь их. И если нет смысла иметь их, нет смысла иметь либо f_x
, f_y
, d_x
, либо d_y
. Все прошло.
Чтобы решить эту проблему, необходимо, чтобы каждая итерация цикла зависела от результатов последней итерации. Вот мое решение этой проблемы. Я использую шаблон complex
для выполнения некоторых вычислений, связанных с вычислением набора Mandlebrot:
#include <iostream>
#include <time.h>
#include <complex>
int main(int argc, char *argv[])
{
using ::std::complex;
using ::std::cout;
const complex<float> f_coord(0.1, 0.1);
const complex<double> d_coord(0.1, 0.1);
complex<float> f_answer(0, 0);
complex<double> d_answer(0, 0);
clock_t start, stop;
const unsigned int N = 200000000; //2*10^8
start = clock();
for (unsigned int i = 0; i < N; ++i)
{
f_answer = (f_answer * f_answer) + f_coord;
}
stop = clock();
cout << "Single Precision: " << (stop-start)/(double)CLOCKS_PER_SEC
<< " " << f_answer << '\n';
start = clock();
for (unsigned int i = 0; i < N; ++i)
{
d_answer = (d_answer * d_answer) + d_coord;
}
stop = clock();
cout << "Double precision: " <<(stop-start)/(double)CLOCKS_PER_SEC
<< " " << d_answer << '\n';
return 0;
}