Domanda

Di recente, mi è stato sfidato in una recente intervista con un problema manipolazione di stringhe e ha chiesto di ottimizzare le prestazioni. Ho dovuto usare un iteratore per spostarsi avanti e indietro tra i caratteri TCHAR (con supporto Unicode - 2bytes ciascuno).

Non proprio pensando alla lunghezza della matrice, ho fatto un errore curiale con non usare size_t ma un int per scorrere. Capisco che non è compatibile e non sicuro.

int i, size = _tcslen(str);    
for(i=0; i<size; i++){
   // code here
}

Ma, la memoria massima che possiamo allocare è limitato. E se c'è una relazione tra int e registrare le dimensioni, può essere sicuro da usare un numero intero.

Es .: Senza alcuni strumenti di mappatura virtuale, siamo in grado di mappare solo 2 byte ^ registrarsi-size. Poiché TCHAR è 2 byte lunghi, metà di quel numero. Per ogni sistema che ha come int 32-bit, questo non sarà un problema, anche se non utilizza una versione unsigned int. Le persone con sfondo incorporato utilizzato per pensare a come int 16-bit, ma la dimensione della memoria saranno limitati su tale dispositivo. Quindi mi chiedo se ci sia una decisione di architettura messa a punto tra il numero intero e registrare le dimensioni.

È stato utile?

Soluzione

Lo standard C ++ non specifica la dimensione di un int. (Si dice che sizeof(char) == 1, e sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long).

Quindi non non sono per essere in una relazione di registrare dimensioni. Un completamente conforme implementazione C ++ potrebbe dare 256 numeri interi byte sul tuo PC con registri a 32 bit. Ma sarebbe inefficiente.

Quindi sì, in pratica, la dimensione del tipo di dati int è in genere uguale alla dimensione di registri di uso generale della CPU, dal momento che è di gran lunga l'opzione più efficiente.

Se un short era più grande di un registro, quindi operazioni aritmetiche semplici richiederebbero più di un'istruzione, il che sarebbe costoso. Se fossero più piccolo di un registro, quindi caricare e memorizzare i valori di un registro richiederebbe il programma per mascherare i bit inutilizzati, per evitare di sovrascrivere altri dati. (Ecco perché il tipo di dati <=> è in genere più efficace di <=>).

(Alcune lingue richiedono semplicemente un <=> essere a 32 bit, in questo caso c'è ovviamente alcuna relazione registrare dimensione --- diverso da quello a 32 bit è scelto perché è un formato comune registro)

Altri suggerimenti

Andando rigorosamente dallo standard, non v'è alcuna garanzia per quanto grande / piccolo int è, tanto meno alcuna relazione alla dimensione registro. Inoltre, alcune architetture hanno diverse dimensioni di registri (cioè: non tutti i registri della CPU della stessa dimensione) e la memoria non è sempre letta utilizzando un solo registro (come DOS con il suo segmento: Offset indirizzamento). Con tutto ciò detto, tuttavia, nella maggior parte dei casi int è la stessa dimensione come i registri "normali" in quanto si suppone essere il tipo di base più comunemente usato ed è quello che le CPU sono ottimizzati per operare.

Per quanto ne sappia, non v'è alcun legame diretto tra la dimensione registro e la dimensione di int.

Tuttavia, dal momento che si sa per quale piattaforma si sta compilando l'applicazione, è possibile definire un tipo alias con tutti i formati desiderati:

Esempio

#ifdef WIN32 // Types for Win32 target
#define Int16 short
#define Int32 int
// .. etc.
#elif defined // for another target

Quindi, utilizzare gli alias dichiarati.

Io non sono del tutto consapevoli, se ho ben capito questo corretto, dal momento che alcuni problemi diversi (dimensioni di memoria, l'allocazione, registrare le dimensioni, le prestazioni?) Sono mescolati qui.

Quello che posso dire è (solo prendendo il titolo), che nella maggior parte dei processori attuali per la massima velocità che si dovrebbe usare numeri interi che corrispondono a registrare dimensioni. La ragione è che quando si usano interi più piccoli, si ha il vantaggio di aver bisogno di meno memoria, ma , per esempio sull'architettura x86, è necessario un ulteriore comando per la conversione. Anche su Intel avete il problema, che accede a unaligned (per lo più sul registro di dimensioni confini) Memoria darà un po 'di penalità. Fuori rotta, su processori odierni cose sono ancora più complesse, dal momento che le CPU sono in grado di elaborare i comandi in parallelo. Così si finisce per la messa a punto per un po 'l'architettura.

Quindi l'ipotesi migliore - senza conoscere l'architectore -. Speeedwise è, per usare registrare interi di dimensioni, il più a lungo si può permettere la memoria

Non ho una copia dello standard, ma la mia vecchia copia di La programmazione linguaggio C , dice (sezione 2.2) int fa riferimento a "un intero, in genere riflette la dimensione naturale del interi sulla macchina host." La mia copia di Il C ++ Programming Language dice (paragrafo 4.6) "il <=> tipo dovrebbe essere scelto per essere il più adatto per la tenuta e la manipolazione di interi su un dato computer".

Non sei l'unica persona a dire "devo ammettere che questo è tecnicamente un difetto, ma non è davvero sfruttabile ".

Ci sono diversi tipi di registri con dimensioni diverse. Ciò che è importante sono i registri di indirizzi, non quelli di uso generale. Se la macchina è a 64 bit, i registri di indirizzi (o una loro combinazione) deve essere di 64 bit, anche se i registri di uso generale sono di 32 bit. In questo caso, il compilatore può essere necessario fare qualche lavoro extra per calcolare effettivamente indirizzi a 64 bit utilizzando più registri di uso generale.

Se non si pensa che i produttori di hardware sempre fare scelte progettuali dispari per i loro registri, allora probabilmente non avete mai avuto a che fare con l'originale 8086 " modalità reale " indirizzamento.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top