2012-06-06 14 views
10

Me pregunto si es una buena idea seguir usando int (que es de 32 bits en x86 y x86_64) en programas de 64 bits para variables que no tienen nada especial y no necesitan abarcar hasta 2^64, como contadores de iteración , o si es mejor usar size_t que coincida con el tamaño de palabra de la CPU.¿Alguna razón para usar enteros de 32 bits para operaciones comunes en la CPU de 64 bits?

Por supuesto, si usa int, guarda la mitad de la memoria, y eso podría significar algo acerca de la caché de la CPU, pero no sé si en la máquina de 64 bits cada número de 32 bits debe extenderse a 64 poco antes de cualquier uso.

EDIT: He realizado algunas pruebas con un programa mío (ver self answer, todavía conservo el de Janneb aunque aceptado porque es bueno). Resulta que hay una mejora significativa en el rendimiento.

+1

Los contadores de iteración no deben estar en la memoria caché de la CPU; deberían residir en registros. –

+0

1. Creo que los compiladores arreglan automáticamente muchas de esas cosas para usted. 2. ¿Por qué no escribes un programa que prueba el rendimiento entre los dos? – Shahbaz

+0

seguro, pero "pero no sé si en la máquina de 64 bits cada número de 32 bits debe extenderse a 64 bits antes de cualquier uso". Y eso fue solo un ejemplo. –

Respuesta

4

Para los índices de matriz y la aritmética de puntero, los tipos que son del mismo tamaño que un puntero (normalmente, size_t y ptrdiff_t) pueden ser mejores, ya que evitan la necesidad de cero o firmar extender el registro. Considere


float onei(float *a, int n) 
{ 
    return a[n]; 
} 

float oneu(float *a, unsigned n) 
{ 
    return a[n]; 
} 

float onep(float *a, ptrdiff_t n) 
{ 
    return a[n]; 
} 

float ones(float *a, size_t n) 
{ 
    return a[n]; 
} 

con GCC 4.4 O2 en x86_64 se genera el siguiente asm:


    .p2align 4,,15 
.globl onei 
    .type onei, @function 
onei: 
.LFB3: 
    .cfi_startproc 
    movslq %esi,%rsi 
    movss (%rdi,%rsi,4), %xmm0 
    ret 
    .cfi_endproc 
.LFE3: 
    .size onei, .-onei 
    .p2align 4,,15 
.globl oneu 
    .type oneu, @function 
oneu: 
.LFB4: 
    .cfi_startproc 
    mov %esi, %esi 
    movss (%rdi,%rsi,4), %xmm0 
    ret 
    .cfi_endproc 
.LFE4: 
    .size oneu, .-oneu 
    .p2align 4,,15 
.globl onep 
    .type onep, @function 
onep: 
.LFB5: 
    .cfi_startproc 
    movss (%rdi,%rsi,4), %xmm0 
    ret 
    .cfi_endproc 
.LFE5: 
    .size onep, .-onep 
    .p2align 4,,15 
.globl ones 
    .type ones, @function 
ones: 
.LFB6: 
    .cfi_startproc 
    movss (%rdi,%rsi,4), %xmm0 
    ret 
    .cfi_endproc 
.LFE6: 
    .size ones, .-ones 

Como puede verse, las versiones con la int e índice unsigned int (onei y oneu) requiere un extra instrucción (movslq/mov) para firmar/extender cero el registro.

Como se mencionó en un comentario, la desventaja es que codificar un registro de 64 bits requiere más espacio que la parte de 32 bits, lo que aumenta el tamaño del código. En segundo lugar, las variables ptrdiff_t/size_t necesitan más memoria que el equivalente int; si tiene tales matrices, ciertamente puede afectar el rendimiento mucho más que el beneficio relativamente pequeño de evitar la extensión de cero/signo. Si no está seguro, perfil!

3

En términos de caché, ahorrará espacio; caché maneja bloques de datos, independientemente de si la CPU solicitó una sola dirección o el fragmento completo es igual al tamaño del bloque de caché.

Así que si está preguntando si los números de 32 bits toman 64 bits de espacio dentro de las memorias caché en las máquinas de 64 bits, entonces la respuesta es no, todavía tomarán 32 bits para ellos. Así que, en general, que le ahorrará un poco de espacio, especialmente si usted está utilizando grandes matrices con frecuentes accesos etc.

En mi opinión personal, un simple int parece más sencillo que size_t y la mayoría de los editores no reconocerán size_t tipo de modo resaltado de sintaxis también será mejor si usa int. ;)

+1

¡Sugiero que dejes de usar cualquier editor que no reconozca 'size_t' inmediatamente! – Shahbaz

+2

Ciertamente deje de usar un editor que no le permite configurar lo que se resalta como un tipo :-) –

+0

en Windows, muchos editores (MS Visual Studio, ultra edit, notepad ++, editplus) no reconocen size_t. si uno se desarrolla en entornos Unix/Linux, entonces es seguro, de lo contrario, bueno, seguro, un poco más desordenado: P de todos modos, este no era el punto principal ... :) – xenodevil

0

Esta debería ser la decisión del desarrollador del compilador.

int es el tipo natural para enteros con signo "normal". Depende del compilador decidir de qué se trata.
Si, en una plataforma específica, hay una ventaja real en el uso de enteros de 64 bits, se espera que el desarrollador del compilador haga int 64bit. El estándar lo permite.

Si el desarrollador del compilador decidió usar enteros de 32 bits, normalmente debería confiar en él.
Tal vez, en algunos casos excepcionales, después de un esfuerzo de optimización significativo, encontrará que long funciona mejor. Entonces es posible que desee cambiar.

3

Estoy codificando un poco hard spheres model. La fuente se puede encontrar en github.

Traté de seguir usando size_t para las variables que se utilizan como índice de matrices, y int donde realizo otras operaciones, no relacionadas con el tamaño de la palabra. La mejora del rendimiento fue significativa: una ~ 27 a ~ 24 caída del tiempo de ejecución.

+0

muy buen ejemplo del mundo real que demuestra el problema en El primer lugar. +1 – hroptatyr

Cuestiones relacionadas