2010-06-14 19 views
8

Nos gusta pensar que el acceso a la memoria es rápido y constante, pero en arquitecturas/sistemas operativos modernos, eso no es necesariamente cierto.¿Cuál es el costo del acceso a la memoria?

Considere el siguiente código C:

int i = 34; 
int *p = &i; 

// do something that may or may not involve i and p 

{...} 

// 3 days later: 

*p = 643; 

Cuál es el costo estimado de esta última asignación de instrucciones de la CPU, si

  • i está en la caché L1,
  • i está en L2 caché,
  • i está en caché L3,
  • i en la memoria RAM es adecuada,
  • i se copia en disco en un disco SSD,
  • i se copia en disco en un disco tradicional?

¿Dónde más puede ser i ser?

Por supuesto, los números no son absolutos, pero solo me interesan los órdenes de magnitud. Intenté buscar en las webs, pero Google no me bendijo esta vez.

+3

Uh si está paginado a cabo el costo de acceso es no determinista ... –

+7

Amigo, si su programa tiene tres días para ejecutar usted tiene problemas más grandes que preocuparse acerca de cuánto tiempo va a tomar para meter en 'p '<\humor>:) –

+0

'¿Dónde más puedo estar?' En algún lugar de la red? a medio camino a través del globo? –

Respuesta

13

He aquí algunos números duros, lo que demuestra que los tiempos exactos varían de familia de CPU y de una versión a otra: http://www.agner.org/optimize/

Estos números son una buena guía:

L1   1 ns 
L2   5 ns 
RAM   83 ns 
Disk 13700000 ns 

Y como una infografía para darle las órdenes de magnitud:

Click for the big view (src http://news.ycombinator.com/item?id=702713)

+7

¿Es solo yo o esa imagen es solo un gran rectángulo rojo honkin '? – paxdiablo

+0

@paxdiablo, sí realmente necesita hacer clic en él para ver la parte superior izquierda, donde la L1 es – Will

+0

La infografía es probablemente correcta, pero el número citado de 13700 ns no lo es. Se parece más a 10,000,000ns (10ms). Fuente: http://www.google.com/moderator/#9/e=7f3&g=Numbers%2520everyone%2520should%2520know –

1

también podría ser en un registro de CPU. La palabra clave "registro" de C/C++ le dice a la CPU que mantenga la variable en un registro, pero no puede garantizar que se mantendrá o incluso que ingresará allí.

+1

La palabra clave C/C++ "register" _suggests_ a _compiler_ que debe mantener la variable en un registro !!! – paxdiablo

+5

Si toma una dirección, ya no puede estar en un registro. – berkus

0

¿Dónde más puedo estar?

i y *i son cosas diferentes, ambos pueden estar situados en cualquiera de los lugares en su lista. La dirección del puntero, además, podría todavía ser almacenado en un registro de la CPU cuando se efectúa la cesión, por lo que no tiene que ser traída desde la memoria RAM/Caché/...

En cuanto al rendimiento: esto es altamente dependiendo de la CPU. Pensando en órdenes de magnitud, acceder a la memoria RAM es peor que acceder a las entradas de la memoria caché y acceder a las páginas intercambiadas es lo peor. Todos son un poco impredecibles porque también dependen de otros factores (es decir, otros procesadores, según la arquitectura del sistema).

1

Mientras la memoria caché/RAM/disco duro/SSD no esté ocupada sirviendo otro acceso (por ejemplo, solicitudes DMA) y el hardware sea razonablemente confiable, el costo es constante (aunque puede ser una gran constante).

Cuando se pierde una memoria caché y se debe acceder al disco duro para leer la variable, es solo una simple solicitud de lectura de disco duro, este costo es enorme, ya que la CPU tiene que: enviar interrupción al kernel para disco duro solicitud de lectura, envíe una solicitud al disco duro, espere a que el disco duro escriba los datos en la RAM, luego lea los datos de la memoria RAM en la memoria caché y en un registro. Sin embargo, este costo sigue siendo un costo constante.

Los números reales y las proporciones variarán dependiendo de su hardware y de la compatibilidad de su hardware (por ejemplo, si su CPU se ejecuta en 2000 Mhz y su RAM envía datos a 333 Mhz, entonces no se sincronizan muy bien) . La única forma en que puede resolver esto es probarlo en su programa.

Y esto no es una optimización prematura, esto es una micro-optimización. Deje que el compilador se preocupe por este tipo de detalles.

+2

Un patrón de acceso a la memoria no óptimo no es algo que el compilador pueda resolver por usted. Necesita escribir el código para acceder a la memoria de la mejor manera. Si le preocupa el rendimiento del resultado, ¡esto no es una optimización prematura! Es solo ahorrarse algo de tiempo al no hacer lo incorrecto en primer lugar. (Además, los errores de caché no están relacionados con el disco duro). –

+0

Sí, no es una optimización prematura; es micro-optimización. Y * es * el trabajo del compilador (y la CPU) reorganizar las instrucciones para minimizar las fallas de caché (y fallas de página). –

+0

Pero no es tarea del compilador, por ejemplo, compilar un árbol B cuando codificó un árbol binario. Un compilador no es un polvo mágico de duendes que puedes rociar en tu código para hacerlo rápido. –

3

Norvig tiene algunos values de 2001. Las cosas han cambiado un poco desde entonces, pero creo que las velocidades relativas son aún más o menos correctas.

1

Estos números cambian todo el tiempo. Pero para estimaciones aproximadas para 2010, Kathryn McKinley has nice slides on the web, que no me siento obligado a copiar aquí.

El término de búsqueda que desea es "jerarquía de memoria" o "costo de jerarquía de memoria".

Cuestiones relacionadas