Вопрос {c++} почему код под номером 2 работает быстрее, чем код под номером 1?

Регистрация
22 Авг 2013
Сообщения
80
Репутация
-3
Спасибо
0
Монет
0
Код номер 1:



const __int64 N = 1000000000;

const float a = 2 * M_PI / ((N - 1) * (N - 1));

float* pfsin = new float[N];

float* pfcos = new float[N];

for (__int64 i = 0; i < N; ++i) {

pfsin = sin(a * i);

pfcos = cos(a * i);

}

delete[] pfsin;

delete[] pfcos;



Код номер 2:



const __int64 N = 1000000000;

const float a = 2 * M_PI / ((N - 1) * (N - 1));

float* pfsin = new float[N];

float* pfcos = new float[N];

for (__int64 i = 0; i < N; ++i) {

pfsin = sin(a * i);

}

for (__int64 i = 0; i < N; ++i) {

pfcos = cos(a * i);

}

delete[] pfsin;

delete[] pfcos;
 
Не быстрее.
В 64-битном дебаге студии: 12s у первого против 13s у второго,
в 64-битном релизе: 6s против 7s
 
pfsin и pfcos размещаются далеко друга в памяти. Когда происходит обращение к элементу (например pfsin), процессор вместе с ним запрашивает копию этого участка памяти в кеш. Куда попадают элементы с индексами i+1, i+2 и т.д. в завимости от размера этого кеша. Поэтому если следующим будет запрошен pfsin[i+1] он будет считан с кеша. Обращения к кешу очень быстрые, и код будет работать быстро.

Если же происходит обращение к pfcos то в кеше его не будет, процессор повторит запрос в память и обновит кеш. И так раз за разом. Код будет работать медленно из за того что кеш будет не задействован.

PS забыл добавить что в древних компьютерах кеш был прямым и тупым, а в современных гораздо хитрее, и вполне может загрузить половину одного участка и половину другого. Так же не забываем об умных компиляторах которые такой код могут выполнить за 0 секунд (ибо никакой полезной работы не выполняется :)
 
Распараллелено во втором случае, поэтому быстрее.
 
Код номер 2 работает быстрее, чем код номер 1, потому что в коде номер 2 вычисления синуса и косинуса разделены на два отдельных цикла. Это позволяет процессору оптимизировать выполнение этих циклов, используя конвейерные вычисления.

В коде номер 1 каждая итерация цикла включает в себя вычисление и синуса, и косинуса, что может привести к тому, что процессор будет ждать завершения одной операции перед началом следующей. Это может замедлить общую скорость выполнения.

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