La memoria

La memoria es uno de los componentes más decisivos en el rendimiento de nuestro PC. Saber cómo funciona nos ayudará a optimizar su funcionamiento...

Cualquier PC está compuesto por una serie de elementos principales: microprocesador, memoria, tarjeta gráfica, discos duros, dispositivos ópticos, etc... Cada uno de estos elementos se descomponen muchas veces en otros; por ejemplo, el micro se descompone en ALU (unidad aritmético-lógica), FPU (unidad de coma flotante), UC (unidad de control), memoria caché de nivel 1, memoria caché de nivel 2, etc...

Pues bien, todos estos elementos se deben comunicar entre sí, en unas ocasiones a través de un tercero y en otras directamente los unos con los otros.

Debido a que un ordenador es algo 'tonto' debemos especificar su sistema de comunicación. En dicho sistema vamos a obviar el lenguaje, ya que no es algo que nos atañe directamente para el tema de frecuencias tratado en esta guía pero, como hemos dicho antes, al ser un sistema 'tonto' es imprescindible indicarle en TODO momento, cuándo un elemento puede enviar datos, cuando no los puede enviar, cuando puede recibirlos y cuando no.

Evidentemente para conocer esto, es imprescindible conocer cómo funciona cada componente, cuánto puede tardar en buscar aquello que quiere enviar y cuánto puede tardar en enviarlo. Si lo pensamos dos veces, esto que acabamos de comentar no es más que un sistema de SINCRONIZACIÓN.

Si bien podemos 'jugar' en mayor o menor medida con las frecuencias de los componentes de nuestro PC, en esta guía nos vamos a centrar en la memoria RAM, la forma más sencilla y eficaz de conseguir una mejora inmediata en nuestro rendimiento.

Manejando el reloj

El sistema de sincronización que emplea un ordenador es una señal de reloj, que es lo que también se conoce como FSB o bus del sistema (en los AMD64 es el HTT, hyper transport).

A continuación se ve la señal de reloj que emplea un ordenador:

Una señal de reloj no es más que una oscilación eléctrica que varía entre dos valores cualesquiera, siempre iguales. Cuando tengamos el valor alto lo llamaremos 1 y cuando tengamos el valor bajo, lo llamaremos 0 (verde oscuro). Hacia arriba tendremos Voltios (electricidad) y hacia la derecha tiempo (color negro), es decir que en el dibujo se ve qué es lo que le ocurre a electricidad a lo largo del tiempo, y como se ve, varía entre 0 y 1, en intervalos exactamente iguales de tiempo y muy rápidamente, siendo todos los ciclos iguales.
 
Cuando la señal sube lo llamamos flanco ascendente, y cuando baja, flanco descendente (verde claro).

Un ciclo o 'Hercio' (color marrón), es el tiempo transcurrido desde que acaba de bajar la señal, hasta que justo termina de bajar una vez más, o viceversa, desde que acaba de subir hasta que sube una vez más, o sea, una subida y una bajada o una bajada y una subida. Parece complicado (y lo es) pero entender mínimamente este proceso nos será muy útil para aprender lo que esta guía intenta enseñar: a sincronizar.

Todos los elementos del ordenador van a funcionar por flanco de bajada o flanco descendente, de este modo, aquel elemento al que le toque hacer algo, leer, escribir, enviar datos, buscar datos, etc... lo hará única y exclusivamente en el momento en el que detecte que la señal de reloj acaba de bajar. De este modo es como tenemos sincronizados todos los elementos del ordenador.

Hay que decir que el reloj del sistema lo gestiona la placa base, y está preparado para el chipset de dicha placa base. Si tenemos una placa base con chipset VIA KT133, pues el reloj del sistema por defecto irá a 133 MHz, o sea que subirá y bajará un total de 133 millones de veces en cada segundo, ahí es nada. En general, hoy día los buses se cifran en 200 MHz.

El primer problema con el que nos encontramos es la sincronización entre el chipset y el procesador, que es mucho más rápido. Es necesario emplear algún sistema nuevo de sincronización, y éste será un divisor o bien un multiplicador. Si el elemento a sincronizar es más rápido que el reloj del sistema emplearemos un multiplicador, que lo que hará será obligar al elemento (en este caso micro) a realizar varias operaciones por cada ciclo de reloj del sistema. Así tenemos que si un micro funciona a 3 GHz, siendo el FSB = 200 MHz, el multiplicador del micro será: 15.

3000 MHz / 200 MHz = 15

El en caso de los periféricos como tarjeta PCI o AGP, tendremos menor número de MHz que en el reloj del sistema, así que emplearemos divisores. Funcionan al revés que los multiplicadores.

Tengamos en cuenta que cuando un elemento funciona a una frecuencia diferente a la frecuencia del bus, se tardará un pequeño tiempo extra en hacer las cosas, así que lo óptimo es un sistema completamente síncrono (todo a la misma velocidad)

Una vez aclarado esto pasamos a ver cómo es la estructura interna de la memoria. La memoria está compuesta por un montón de celdas, colocadas de manera estratégica. Imaginemos un tablero de ajedrez, pero en lugar de con 64 posibles posiciones donde colocar piezas, con n posiciones. Pues la memoria es parecida, pero como esto se nos queda un poco corto para meter todos nuestros datos, en lugar de usar un solo tablero de ajedrez, emplearemos varios. En cada posición, podremos meter un dato o una instrucción.

¿Por qué poner varios tableros en lugar de un solo tablero pero muy grande? Imaginemos que tenemos 90 filas y 90 columnas. Si queremos poner 120 filas y 120 columnas, efectivamente tendríamos un montón más de espacio, de 8100 celdas pasaríamos a 14400, PERO cuando queremos especificar una de estas celdas pasaríamos de tener que meter dos números de 2 dígitos cada uno, a tener que meter dos números pero de 3 dígitos cada uno. Esto con número en base 10, si lo hacemos con números en base 2 (binario, solo 1's y 0's, que es como funcionan los ordenadores) se magnifica bastante, por ejemplo con 3 dígitos solo llegaríamos a 8 posibilidades y con 4 hasta 16... Entonces, para indicar dónde se encuentra ubicado nuestro dato o instrucción dentro del tablero, necesitaríamos dos números enormes de grandes.

Empleando una 'tercera dimensión' ahorramos bastante en direccionamiento. El direccionamiento ocupa bastante, así que es necesario un sistema lo más eficiente posible (no confundir eficiencia con efectividad, un sistema eficaz sería uno solamente con 1 fila, pero larguísima, accedería al dato muy fácilmente y en muy poco tiempo, pero no sería eficaz ya que para indicar dónde se encuentra el dato habría que meter un número de dirección enorme. Uno eficiente es aquel que consigue sus objetivos empleando el menor número de recursos posibles, que es el que tenemos, en 3D).

Esto de los diferentes tableros lo veremos un poco más adelante.
Los datos e instrucciones se almacenan en las celdas de los tableros, y cuando queremos acceder a ellos tendremos que indicar el tablero, la fila y la columna.

Bien, ahora que sabemos cómo es la estructura física que tiene la memoria vamos a ver cómo acceder a los datos o cómo almacenarlos, que es donde entran en juego las latencias.

Cuando queremos acceder a una posición o celda de la memoria, lo que tenemos que hacer es en primer lugar colocarnos en el tablero adecuado, luego situarnos dentro de ese tablero en la fila correspondiente y finalmente colocarnos en la columna donde se encuentra nuestro dato/instrucción. Con esas tres coordenadas tendremos todo lo necesario para acceder a nuestro dato.

El tiempo que tarda la memoria en colocarse en la posición necesaria es relativamente pequeño, sin embargo son tantos los datos e instrucciones que almacenamos en la memoria, que al final el proceso puede llegar a hacerse lento.

Debido a que se van a leer/escribir un montón de datos de la memoria, necesitamos un sistema que lea muchas celdas de golpe, sin transportar los datos de dichas celdas y a continuación, transportar todos los datos a la vez. Este sistema de leer muchas celdas y después transportar es conocido como bus a ráfagas o burst.

Ahora tenemos un sistema de lectura escritura en memoria óptimo, solo faltan las latencias, ya llegamos...

El orden en el que se lee / escribe la memoria es el siguiente:


Primero se coge un tablero, y dentro de ese tablero se coge una fila, de esa fila se lee la primera celda ‘1 A', luego se lee la siguiente celda de esa fila, la ‘1 B', luego la ‘1 C', y finalmente, la ‘1 D'. Luego se pasa a otra fila y se leen sucesivamente las celdas 2 A, 2 B, 2 C y 2 D. Este proceso se repite hasta terminar con todo el tablero, momento en el que pasaremos al siguiente tablero. El situarnos en una determinada fila cuesta cierto tiempo. El colocarnos en una determinada columna cuesta también cierto tiempo (Ambos tiempos son diferentes). Si cada cambio de fila y / o columna tenemos que esperar cierto tiempo, podemos observar en el ejemplo que por cada lectura de tablero tendremos que esperar el tiempo de cambio de columna 16 veces, mientras que el de fila lo tendremos que esperar solo 4 veces. Si en lugar de tener un tablero de 4 X 4 tuviéramos uno de  100 X 100 tendríamos que esperar al tiempo de salto de columna 10000 veces, mientras que al de fila solamente 100 veces.

Bien, pues... y si ahora os dijéramos que el tiempo que tarda la memoria en colocarse en una determinada columna se llama Latencia CAS? Efectivamente ese tiempo es el denominado como CAS, latencia CAS, CAS Latency o CL.

Tal y como os acabamos de demostrar es el tiempo más importante de una memoria en lo que a latencia se refiere. Una buena latencia hace a una memoria ser muy codiciada. Además, casi todas las memorias indican el CAS en la pegatina que las identifica o en su caja.

El significado de las siglas CAS es Column address strobe o column access strobe y efectivamente, es el tiempo de demora para acceder a una columna o para 'apuntar' a una columna.

Por otro lado el tiempo que tarda en colocarse la memoria en una determinada fila se llama RAS: Row Address/access strobe. Pero tal y como se demuestra más arriba, este tiempo es muchísimo menos importante que el CAS.

Estas dos latencias quedan claras y son indiscutibles, además NO se pueden solapar. Ahora imaginemos que durante la ráfaga tenemos que cambiar de tablero, aquí entran en juego 2 nuevas latencias.
Cuando queremos situarnos en un tablero para poder leer/escribir en él, tenemos que bloquearlo, para que nadie ni nada más pueda modificar o leer sus datos, por lo tanto habrá que enviarle una señal, que llamaremos ACTIVE y que es una nueva latencia, ya que durará un determinado tiempo que evidentemente será mejor cuanto menos dure.

Durante el tiempo que tarda la señal ACTIVE, tendremos que esperar, igual que ocurre con las otras dos señales CAS y RAS.

Finalmente, cuando tengamos que pasar de un tablero a otro, primero tenemos que desbloquear el banco activo y activar uno nuevo, para desbloquear tenemos la última de las latencias, PRECHARGE y también tardará un tiempo.

La señal PRECHARGE tiene una pequeña excepción respecto a las demás. Mientras un tablero se está desbloqueando, podemos activar otro, o sea que las señales PRECHARGE y ACTIVE SÍ se pueden solapar, pero SÓLO cuando se trate de dos tableros diferentes.

Resumiendo las cuatro latencias:
• CAS - Tiempo que se tarda en colocarse en una columna, el más  importante.
• RAS - Tiempo que se tarda en colocarse en una fila.
• ACTIVE - Tiempo para activar/bloquear un tablero.
• PRECHARGE - Tiempo para desactivar/desbloquear el tablero.

Entonces, cuando queremos leer un dato, tendremos que hacer lo siguiente:
1. Mandar una señal ACTIVE al banco correspondiente para activarlo.
2. Esperar a que termine el tiempo de activación (latencia ACTIVE)
3. Mandar una señal para saber cual es la fila en la que nos queremos situar (latencia RAS)
4. Esperar a que se sitúe la fila
5. Mandar la señal que activará la celda, o columna (latencia CAS)
6. Esperar a que se situe.
7. Leer (esto es instantáneo)
8. Saltar a la siguiente celda (CAS) tantas veces como sean necesarias hasta terminar la ráfaga
9. Si corresponde, saltar a la siguiente columna
10. Si corresponde saltar al siguiente banco, señal PRECHARGE y señal ACTIVE solapadas.

Esta es una explicación muy simplificada de cómo se realiza el acceso a memoria. Una vez comprendido podemos empezar a estudiar lo que realmente nos interesa: Las señales de sincronización.


Una latencia es... 'cierto tiempo'. Tenemos que coger dicho tiempo, y ver cuántos ciclos tarda en ejecutarse. Esto depende de cuántos ciclos por segundo se hagan.

Imaginemos que tenemos una frecuencia de bus FSB/HTT de 200 MHz, esto indica que tenemos 200 millones de ciclos por segundo, por lo tanto un ciclo durará...

F = 1 / T  200 * 10^6 = 1 / T  T = 1 / 200 * 10^6  T = 5 * 10^-9 seg

5 ns (nanosegundos), que es 10 elevado a menos 9, ya que los 200 es megaherzio, o 10 elevado a 6

NOTA: Las antiguas memorias RAM que empleaban los Pentium I eran de 70 ns, las EDO que eran las mismas un poco evolucionadas eran de 60 ns, así se puede calcular bastante fácilmente el FSB de aquellos sistemas. Las primeras SDRAM que aparecieron, las PC 100, eran de 10 ns, evidentemente el FSB de aquellos sistemas era de 100 MHz.

Ahora podemos hacer un nuevo dibujo:

Las modernas memorias RAM, son conocidas como DDR SDRAM, Double Data Rate Synchronized Random Access Memory (Memoria de acceso aleatoria dinámica sincronizada con ratio de doble dato). ¿Esto qué es? Pues como la memoria ha evolucionado bastante más en cuanto a velocidad que los chipsets, tenemos que hacer algo para conseguir que la memoria aumente su velocidad.

Podríamos ponerle un multiplicador, pero ha sido más fácil y eficiente hacer que se lea o escriba tanto cuando la señal de sincronización sube como cuando baja. De ahí que se llame DDR. Por lo tanto, cuando tengamos un FSB/HTT de 133 MHz, la memoria será de 266, y cuando la FSB sea de 200, la memoria deberá ser DDR 400.

A este modo de lectura/escritura se conoce por funcionamiento por flanco. Antes trabajábamos con funcionamiento por flanco descendente; la memoria, por flanco a secas, tanto cuando sube como cuando baja.

Ahora sigamos con las latencias… ¿cuánto tarda una memoria en colocarse en una columna determinada? Pues depende de la calidad de la memoria que, a su vez, viene marcada por sus latencias. De este modo, ¿qué latencia CAS, en ciclos podríamos tener en una memoria, si funciona el bus a 200 MHz, y la latencia CAS tarda 12.5 ns? Veamos un dibujo...

Ahí se ve que la memoria tarda 12.5 ns en hacer el CAS, si cogemos 3 ciclos nos llega (Tendríamos latencia CAS 3) PERO nos sobran 2.5 ns.

2.5 en 15 es mucho, el 16.6%, y más aun teniendo en cuenta que se hacen constantes accesos a memoria. En este caso, la optimización de la latencia buscando el ahorro de ese 16% redundaría en la mejora de nuestros rendimientos.

Si prestamos atención al anterior gráfico nos daremos cuenta de que la memoria es DDR, por lo tanto podemos parar tanto en el flanco de bajada como en el de subida. La latencia puede ser un número entero o un número decimal, siendo siempre el decimal 0.5.
 
Miremos el siguiente dibujo:

Aquí vemos que podemos parar cuando se llevan exactamente 2.5 ciclos y nos ahorramos ese 16.6%, con lo que conseguimos muchísimo más rendimiento en los accesos a la memoria. Tenemos una latencia CAS de 2.5.
Los ordenadores aceptan latencias CAS de 2, 2.5 o 3.

La diferencia de latencia es determinante a la hora de medir el rendimiento del ordenador ya que cualquier operación que hacemos con él requiere obligatoriamente acceder multitud de veces a la memoria. Por cada celda del tablero que queramos leer, tenemos que esperar la latencia CAS, por cada fila completa al RAS, y por cada tablero diferente las ACTIVE y PRECHARGE (a veces se solapan).  Dijimos que se leía por ráfagas, pero en cada ráfaga se espera ‘x' veces a CAS, ‘y' veces RAS, siendo X = Y^2, ACTIVE, PRECHARGE, etc... Por tanto se han de hacer varias esperas a CAS por cada ráfaga.

Ahora, otra cosa importante; 'cuanto más subamos el FSB, más rendimiento tendremos.' Esto es una verdad a medias. Las latencias son inversamente proporcionales a la velocidad del bus FSB/HTT, es decir, cuanto mejor FSB tengamos, peor latencia tendremos y viceversa. Veamos un dibujo:

Mirando el dibujo, vemos que tenemos dos sistemas: uno con un FSB de 100 MHz (izquierda) y otro, con un FSB de 200 MHz (derecha). Al tener el doble de frecuencia tenemos que en el mismo tiempo se hacen el doble de ciclos, de ahí que a la derecha tengamos las 'ondas' muchos más comprimidas. En ambos casos tenemos que la misma memoria tarda un mismo tiempo en hacer el acceso CAS (Este tiempo está marcado con una línea verde). La escala de tiempo en ambos casos es exactamente la misma, así que la línea verde será en ambos casos exactamente igual.
 
Para el sistema de la izquierda, podemos ver que el CAS de la memoria será de casi 2 ciclos. Para redondear evidentemente tenemos que redondear hacia arriba para darle tiempo a que termine. Sobrará un poco, sin embargo, para el caso de la derecha, el CAS sería de 3. De este modo podemos ver gráficamente la diferencia de CAS, y cómo al ir subiendo FSB hay que ir poniendo latencias peores.
Vamos a ver un dibujo para ver lo que se desperdicia en cada caso:


 Mirando el dibujo, vemos que en la parte de la izquierda perdemos un poco de tiempo desde que se termina el CAS hasta que termina su latencia. Lo mismo pasa en el sistema del dibujo de la derecha, pero en este caso es más tiempo (Recordemos que la escala temporal, eje de las abscisas, es el mismo en ambos casos, por lo tanto el tiempo es mayor a la derecha).

En principio se podría pensar que aunque se pierda un poco más en un lado que en el otro, como el FSB es bastante superior, seguro que es más rápido aun perdiendo un poco de tiempo en el CAS... Vamos a demostrar matemáticamente como esto no es siempre cierto:

Tengamos un sistema a 166 MHz y otro a 200 MHz, y vamos a usar exactamente la misma memoria en ambos casos. Calculemos cuánto tarda en ejecutarse un ciclo:

1/166 * 10^6 = 6 * 10^-9 = 6 ns
1/200 * 10^6 = 5 * 10^-9 = 5 ns

Bien, un ciclo en el sistema con bus a 200 MHz tarda 5 nanosegundos en ejecutarse y 6 nanosegundos en el sistema con bus a 166 MHz. Supongamos que la memoria funciona en ambos sistemas con las siguientes latencias:

Sistema 166 MHz - 2 - 2 - 2 - 5  CAS, RAS, PRECHARGE y ACTIVE
Sistema 200 MHz - 3 - 2 - 2 - 5  CAS, RAS, PRECHARGE y ACTIVE

Lo único que cambia es el CAS, de ser 2 pasa a ser 3. Al tener CAS 2 y funcionar a 166 el bus el tiempo de desperdicio es muy pequeño, y al ser CAS 3 en el sistema con bus a 200 el tiempo de desperdicio es muy grande. Con CAS 2.5 no le daría tiempo a la memoria.

Los tiempos que se tardarían en cada caso serían los siguientes:

Sistema 166 MHz:
(2 * 6) + (2 * 6) + (2 * 6) + (5 * 6) = 12 + 12 + 12 + 30 = 66 ns
Sistema 200 MHz:
(3 * 5) + (2 * 5) + (2 * 5) + (5 * 5) = 15 + 10 + 10 + 25 = 60 ns

Hasta aquí parece que salen mal las cuentas ya que el sistema con bus a 200 MHz tarda menos tiempo; 60 ns contra 66 ns. Sin embargo, si suponemos que el tablero de la memoria es de 100 filas por 100 columnas las cosas cambian.

Recordemos que la latencia CAS se ejecuta tantas veces como columnas tengamos, en este caso 100 veces por cada vez que se ejecuta la RAS. Por lo tanto, el cálculo justo, suponiendo que tenemos que leer en una ráfaga justo una fila entera quedaría de la siguiente manera:

Sistema 166 MHz:
[100 * (2 * 6)] + (2 * 6) + (2 * 6) + (5 * 6) =
(12 * 100) + 12 + 12 + 36 = 1200 ns + 66 ns = 1266 ns

Sistema 200 MHz:
[100 * (3 * 5)] + (2 * 5) + (2 * 5) + (5 * 5) =
(15 * 100) + 10 + 10 + 25 = 1500 ns + 45 ns = 1545 ns

Evidentemente este sería el caso ideal, que justo haya que leer una fila entera y no hubiera que hacer ni un solo salto de fila (RAS) ni cambios de tablero. Aunque aun así seguiría siendo mejor el caso del sistema con bus a 166 que del bus a 200.

Con ese cálculo creo que queda completamente clara la importancia de la latencia CAS con respecto a las demás, y la importancia de las latencias con respecto al bus FSB/HTT.

Ahora podéis haceros todos los cálculos que queráis y ver cuál sería mejor en cada caso, y si estáis configurando bien vuestras BIOS. Ni qué decir tiene que necesitaréis saber cómo está compuesta físicamente vuestra memoria, es decir, número de filas, columnas, tableros, tamaño de las ráfagas, etc, etc, etc...

Debido a que estos datos es complicado conocerlos, lo más fácil es probar, probar y probar… Como es también imprescindible en el overclocking, habremos de perder tiempo con nuestro sistema y cuantos más intentos hagamos mejor podremos ajustar nuestro sistema.

Sentimos mucho no poder dar un dato objetivo, un 'truco' para poder optimizar el CAS de nuestra memoria en un par de minutos, pero eso es algo que no existe. Sin embargo sí que esperamos haberos permitido entender 'más o menos' cómo funciona internamente una memoria y qué es 'eso del CAS' y la importancia de elegir una buena memoria la próxima vez que compremos un PC.

Si queréis profundizar en el tema un poco más afondo, podéis coger vuestra memoria, mirar el número que aparece serigrafíado en cada uno de los chips que tiene y copiarlo en google. Por ejemplo tenemos por aquí una memoria de 256 MB DDR 266 cuya serigrafía es 'mt46v16m8tg-75z'. Lo copiamos en google y aparece como primera respuesta esta web de su fabricante Micron: http://www.micron.com/products/dram/ddrsdram/part.aspx?part=MT46V16M8TG-75Z

Ahí están las características del chip de memoria. Desde esa web puedes descargarte las hojas de datos de ese chip concreto. Siempre suelen estar en PDF y, como veréis, requieren ser un pequeño 'gurú del hardware' para desenvolverse con ellos