2013-06-29 24 views
7

przetłumaczyłem kod here w C++ następującoWydajność size_t w C++

#include <iostream> 

using namespace std; 

int t = 20; 

bool is_evenly_divisible(const int a, const int b) { 
    for (int i=2; i<=b; ++i) { // Line 1 
     if (a%i != 0) 
      return false; 
    } 
    return true; 
} 

void run() { 
    int i = 10; 
    while (!is_evenly_divisible(i, t)) { 
     i += 2; 
    } 
    cout << i << endl; 
} 

int main(int argc, char** argv) { 
    run(); 
    return 0; 
} 

z flagą -O3 na kompilator g ++ 4.8.1 na Mac OSX 10.8.4, mam czas 0.568s czas użytkownika.

Teraz, jeśli zmienię licznik i w linii 1 w funkcji is_evenly_divisible na size_t, czas nagle skacze do 1,588s. Ta informacja powtarza się, nawet jeśli zmienię wszystkie zmienne na size_t, czas wzrasta do 1.646s

Co się dzieje? Czy nie powinno się zwiększać wydajności, a nie zmniejszać ją, ponieważ jest to bardziej specyficzny typ niż int?

+0

'int' to" naturalny rozmiar "dla sprzętu. –

+4

Czy to działa w systemie 64-bitowym? int to 4 bajty ... – Opt

Odpowiedz

14

int jest zwykle najszybszym typem wszechstronnym. Ta właściwość nie jest wymagana przez standard, ale zazwyczaj ma to miejsce w przypadku dzisiejszych platform. Mamy również coś takiego jak cstdint's int_fast32_t, który jest lepiej zagwarantowany, aby być najszybszym typem, który może pomieścić co najmniej 32 bity - bardzo polecam je do wrażliwego kodu!

size_t nie jest przeznaczony do podania szybkiej liczby całkowitej. Jego celem jest zapewnienie liczby całkowitej, która może pomieścić rozmiar największego obiektu, jaki może zawierać przestrzeń adresowa twojej platformy. Zazwyczaj size_t jest odpowiednikiem największej "naturalnej" liczby całkowitej obsługiwanej przez procesor, ale nie musi tak być.

Zgaduję, że jesteś na platformie 64-bitowej. Zasadniczo platforma 64-bitowa ma mniej więcej równy przepływ dla operacji 32-bitowych i 64-bitowych, ale trafiłeś w jedno miejsce, w którym zazwyczaj nie są: div/mod może być 2-3-krotnie wolniejszy na 64-bitowej liczbie całkowitej . W tym przypadku, jeśli int jest 32-bitowy, a size_t jest 64-bitowy, ładnie to wyjaśnia.

Zobacz dokument instruktażowy , aby uzyskać więcej informacji. Na platformie Sandy Bridge firmy Intel pokazuje 32-bitowy element div z opóźnieniem wynoszącym 20-28 cykli, a dysk 64-bitowy przyjmuje od 30 do 94 cykli.

+0

Jestem zaskoczony GCC nie zdaje sobie sprawy, że 'i' nie może być większy niż' b'. – Bernard

1

Rozmiar size_t jest zdefiniowany przez implementację, a jeśli korzystasz z maszyny 64-bitowej, większość kompilatorów ma rozmiar 8-bajtowy.

Operacje z 8-bajtowymi liczbami całkowitymi są zwykle wolniejsze niż w przypadku 4-bajtowych analogów.