rozważa następujące programy testowe:Dlaczego dereferencje powodują, że mój program jest szybszy?
int main(void) {
int iterations = 1000000000;
while (iterations > 0)
-- iterations;
}
Loop value on the stack (dereferenced)
int main(void) {
int iterations = 1000000000;
int * p = & iterations;
while (* p > 0)
-- * p;
}
#include <stdlib.h>
int main(void) {
int * p = malloc(sizeof(int));
* p = 1000000000;
while (*p > 0)
-- * p;
}
Przez zestawiania ich ze -O0, mam t on następujące czasy wykonania:
case1.c
real 0m2.698s
user 0m2.690s
sys 0m0.003s
case2.c
real 0m2.574s
user 0m2.567s
sys 0m0.000s
case3.c
real 0m2.566s
user 0m2.560s
sys 0m0.000s
[edytuj] Poniżej znajduje się średnio na 10 egzekucji:
case1.c
2.70364
case2.c
2.57091
case3.c
2.57000
Dlaczego czas realizacji większy od pierwszego przypadku testowego, który wydaje się być najprostszą?
Moja obecna architektura to wirtualna maszyna x86 (Archlinux). Otrzymuję te wyniki zarówno z gcc (4.8.0) i clang (3.3).
[edytuj 1] Wygenerowane kody asemblera są prawie identyczne, z wyjątkiem tego, że drugi i trzeci mają więcej instrukcji niż pierwszy.
[edycja 2] Te wykonania są odtwarzalne (w moim systemie). Każde wykonanie będzie miało ten sam rząd wielkości.
[edytuj 3] Nie interesuje mnie wykonanie niezoptymalizowanego programu, ale nie rozumiem, dlaczego byłby wolniejszy i jestem ciekawy.
Czy próbowałeś spojrzeć na wygenerowany kod? Dlaczego tak czy inaczej zależy Ci na wydajności niezoptymalizowanego kodu? –
Hae próbowałeś je uruchomić w innej kolejności? Czy są to jednorazowe czasy, czy średnie na znacznej liczbie przebiegów? – EJP
@CarlNorum Prawie ten sam wygenerowany kod, z wyjątkiem tego, że w dwóch ostatnich przykładach jest więcej instrukcji (przenoszenie i ładowanie). Nie interesują mnie występy, ale nadal jestem ciekawy :) –