2013-06-29 10 views
7

ho tradotto il codice here in C++ come segueprestazioni di size_t in 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; 
} 

Con la bandiera -O3 sul compilatore g ++ 4.8.1 su Mac OSX 10.8.4, avrò tempo 0.568s tempo all'utente.

Ora se cambio il contatore i in Linea 1 in funzione è_evenibilmente_divisibile in size_t, il tempo improvvisamente salta a 1,588 s. Questo persiste anche se cambio tutte le variabili in size_t, il tempo sale a 1.646s

Cosa sta succedendo? Non dovrebbe size_t aumentare le prestazioni piuttosto che diminuirle in quanto è un tipo più specifico di int?

+0

'int' è" la dimensione naturale "per l'hardware. –

+4

Tiene questo su un sistema a 64 bit? int è 4 byte ... – Opt

risposta

14

int è di solito il tipo più veloce a tutto tondo. Questa proprietà non è richiesta dallo standard, ma di solito è il caso delle piattaforme odierne. Abbiamo anche cose come il int_fast32_t di cstdint, che è più propriamente garantito che sia il tipo più veloce che può contenere almeno 32 bit: lo consiglio vivamente per il codice perf-sensitive!

size_t non è progettato per fornire un numero intero veloce. Il suo scopo è quello di fornire un numero intero che possa contenere la dimensione dell'oggetto di dimensioni maggiori che lo spazio indirizzo della piattaforma può contenere. In genere, size_t equivale al più grande intero "nativo" supportato dalla tua CPU, ma non deve esserlo.

Ho intenzione di indovinare che sei su una piattaforma a 64 bit. Generalmente una piattaforma a 64 bit ha circa lo stesso risultato per le operazioni a 32-bit e 64-bit, ma hai raggiunto il punto in cui in genere non lo sono: div/mod può essere in realtà 2-3 volte più lento su un numero intero a 64-bit . In questo caso se int è a 32 bit e size_t è a 64 bit, spiega bene il problema.

Vedere il documento sulle tabelle di istruzioni Agner Fog's per ulteriori informazioni. Per la piattaforma Sandy Bridge di Intel, mostra che il div a 32 bit ha una latenza di 20-28 cicli mentre il div a 64 bit richiede 30-94 cicli.

+0

Sono sorpreso che GCC non si renda conto che 'i' non può essere più grande di' b'. – Bernard

1

La dimensione di size_t è definita dall'implementazione e se si esegue la macchina a 64 bit, la maggior parte dei compilatori lo renderebbero lungo 8 byte.

Le operazioni con numeri interi a 8 byte sono in genere più lenti rispetto agli analoghi a 4 byte.