PDA

Ver la Versión Completa : como cargar y descargar la Ram


kurono
28-08-2008, 02:10:10
hola amigos me gustaria crear una especie de bucle que me cargue la memoria ram y pido disculpan si no uso el termino correcto

coso
28-08-2008, 10:44:29
pues...no se te entiende muy bien, pero si lo que quieres es agotar la memoria, puedes ir creando objetos y no descargarlos de ella...


var
i : integer;
s : PChar;
begin
for i := 0 to 10000000 do
getmem(s,2147483647);
// quiza tengas que usar otra funcion, no getmem
end;


esto, claro, tiene una utilidad nula, a no ser que sea para un 'ataque' o algo asi

kurono
28-08-2008, 20:16:55
con esa funcion me da error cual otra funcion se puede usar

debo decir que no quiero hacer ningun tipo de ataque pues lo que quiero hacer es probar la memoria para determinar con un cronometro que tiempo trascurre entre una descarga y una carga de la memoria

coso
28-08-2008, 20:23:21
te da error porque era para dar error...te llena la memoria hasta que te la agota, y entonces te salta el error... prueba con un try...except, y cuando te salte la excepcion, es que la memoria esta 'cargada' al maximo (bueno, asignada, bloqueada, si quieres medir el tiempo de lectura/ escritura deberas hacer lo analogo con read, write)

kurono
28-08-2008, 20:26:41
ok dejame modificar un poco el codigo luego te cuento

kurono
28-08-2008, 21:07:09
disculpa coso podias darme un ejemplo de como medir el tiempo de lectura/escrituara de la memoria ram

coso
28-08-2008, 21:17:33
pues sinceramente...estaba buscando algo como readblock o algo asi y no lo he encontrado. Lo q se me ocurre es:

- creas un loop for ...next de, por ejemplo, 10000 ciclos y mides su tiempo
- dentro de otro loop for...next, pones algo asi como s[i] := 1, y mides su tiempo. Restando el tiempo del loop vacio, Sera el tiempo de escritura
- dentro de otro, haces temp := s[i] y sera el tiempo de lectura (restando el del loop vacio).

No se me ocurre nada mas :confused: no se si sera diferente velocidad si se asignan enteros o chars (supongo que si) o si delphi usa algun tipo de verificacion en las asignaciones (que tambien lo creo) por lo q te daria una medida erronea. Prueba de hacer una busqueda por 'benchmark', a ver q encuentras...saludos

kurono
28-08-2008, 21:33:25
ok lo probare a ver

cHackAll
28-08-2008, 22:00:50
Para acceder a la memoria RAM necesitas modificar los privilegios de acceso a dicho objeto (restringido por su naturaleza crítica), luego realizar un mapeado del mismo en tu proceso y leer por bloques razonables múltiplos de 4 Kb que es el tamaño del PAGE_SIZE en arquitecturas x86.

La taza de trasferencia pico de las memorias utilizadas en la actualidad es de 1.6 Gb por segundo en DDR-200 a los fascinantes 8.5 Gb/s de DDR2-1066.

Si tu objetivo es leer la memoria virtual utilizada por tu proceso, la cosa cambia un poco puesto que en la misma no solo interviene la memoria física, sino también la temporal en la que el disco duro es el huésped de los datos... si realizas un proceso X de E/S varias veces el SO realiza un caché y la velocidad mejora considerablemente moviendo la información "de un lado para otro" para dicho fin.

Para cronometrar tus procesos usa GetTickCount como comenta coso, considerando que en memoria virtual no hay la limitante del tamaño de paginación, también considera los parámetros con los que reservas la memoria (MEM_MOVEABLE, ZEROINIT, etc, etc.), pues los mismos cambiarán la forma en que el SO optimizará dicho recurso.

Saludos (http://en.wikipedia.org/wiki/DDR2_SDRAM#Specification_standards)

HySTD
29-08-2008, 00:38:18
Para acceder a la memoria RAM necesitas modificar los privilegios de acceso a dicho objeto (restringido por su naturaleza crítica)

Puedes utilizar la función VirtualProtect de la api win32.

Cabe decir que hay que tener en cuenta los accesos a la caché del procesador (en todos los niveles).

También hay que pensar que cuando uno o varios procesos ocupan todo el espacio de memoria física, el sistema operativo irá paginando a disco y reemplazando aquellos segmentos según un criterio (LRU, FIFO, aleatorio, etc...), aunque bien es cierto que los Sistemas operativos optan por reducir la frecuencia de fallos más que encontrar un buen algoritmo de reemplazo, pero esto no viene al caso. A parte, existe la paginación a nivel de hardware, cuyas páginas son de tamaño fijo. Hoy en dia se suele utilizar la segmentación paginada que es una mezcla de los dos.

Para evitar que cierta región de memoria no sea paginada se suelen utilizar drivers, que son precisamente eso: procesos que se ejecutan en espacio protegido (modo kernel) y que no son paginados.

Por tanto es difícil medir cuando la RAM se llena y cuándo no; puedes establecer una cota basándote en la capacidad de ésta, no obstante si realmente quieres testear la RAM puedes optar por hacer un driver.

Un saludo.

cHackAll
29-08-2008, 01:22:36
Para acceder a la memoria RAM necesitas modificar los privilegios de acceso a dicho objeto (restringido por su naturaleza crítica) Puedes utilizar la función VirtualProtect de la api win32.

Me temo que esa API esta orientada a otro tipo de memoria;

The VirtualProtect function changes the access protection on a region of committed pages in the virtual address space of the calling process...

Cabe decir que hay que tener en cuenta los accesos a la caché del procesador (en todos los niveles).

Hablamos de caché L1, L2,... propios del microprocesador? estoy confundido (http://en.wikipedia.org/wiki/CPU_cache#Multi-level_caches)!

Saludos

kurono
29-08-2008, 02:53:23
amigos mio veo que se estan confundiendo pues yo estoy hablando de la memoria ram fisica no de la memoria virtual ni la memoria cache L2 , lo que quiero es medir el tiempo de lectura/escritura de la memoria ram que por cierto todavia no e podido hacer pues le pido que me ofrescan un ejemplo en codigo para tener por donde empezar no le pido mucho solo un ejemplo sencillo pues lo acomodare a mi necesidad

Ñuño Martínez
29-08-2008, 09:46:18
Si quieres saltarte las cachés deberás currártelo más. Por un lado, deberás utilizar datos aleatorios, pero muy aleatorios, para evitar que el sistema de predicción del microprocesador utilice la caché. También debería cambiar la dirección de memoria donde realiza dichas lecturas y escrituras por lo mismo. Por otro lado, el código ejecutable también se cachea y se "predice", lo cual también afecta.

Hoy en día es muy difícil establecer el rendimiento de un algoritmo ya que los programas de pruebas suelen ser mucho más pequeños y con necesidades menores de memoria, lo cual hace que se falseen los datos por culpa de las cachés. Fíjate en cómo funcionan esos programas de comprobación de memoria RAM. Observa que utiliza multitud de patrones diferentes (los va nombrando según los utiliza, algunos incluso muestran en pantalla representaciones gráficas de lo que están haciendo) precisamente para que el trabajo se realice en la memoria RAM real y no en las cachés o en los registros. Tal vez debas echar un vistazo al código fuente de alguno de estos programas (hay varios para GNU/Linux), aunque creo que todos están escritos en C y ensamblador, que en mi opinión son más adecuados que Pascal para estos menesteres (por temas de control de optimizaciones, no por potencia o capacidad).

kurono
29-08-2008, 18:44:35
si estas pruebas utilizan de alguna forma la cache entonces me gustaria ver un ejemplo de codigo utilizando la cache en delphi. por otro lado me puse hacer una prueba de este tipo con el programa pc winsid y es verdad utiliza tanto la cache como el procesador para realizar la prueba

HySTD
30-08-2008, 02:52:07
Me temo que esa API esta orientada a otro tipo de memoria

VirtualProtect permite modificar permisos de lectura/escritura en cierta región de memoria del espacio de usuario dentro del programa actual. No sé a qué te refieres con "otro tipo de memoria"...¿Según tú, entonces VirtualProtect a qué memoria hace referencia? :)

Hablamos de caché L1, L2,... propios del microprocesador? estoy confundido (http://en.wikipedia.org/wiki/CPU_cache#Multi-level_caches)!

Si. Cuando dices "propios del microprocesador" no sé bien a qué te refieres, si a ¿dentro o fuera del chip? da igual, en la jerarquía de memoria de un sistema actual, es el primer nivel (sin contar los registros de la CPU) al cuál se accede (ya sea para carga o almacenamiento).

Si quieres saltarte las cachés deberás currártelo más

La memoria caché no se "salta". Son accedidas a nivel hardware desde el principio.

Un saludo.

cHackAll
30-08-2008, 03:05:28
VirtualProtect permite modificar permisos de lectura/escritura en cierta región de memoria del espacio de usuario dentro del programa actual. No sé a qué te refieres con "otro tipo de memoria"...

Pues no discuto la funcion de la API, sino que como ya confirmó Kurono; no nos interesa la memoria lineal virtual, sino la física!

¿Según tú, entonces VirtualProtect a qué memoria hace referencia?

"Segun yo" ??? :D

Cabe decir que hay que tener en cuenta los accesos a la caché del procesador (en todos los niveles).

...da igual, en la jerarquía de memoria de un sistema actual, es el primer nivel (sin contar los registros de la CPU) al cuál se accede (ya sea para carga o almacenamiento)...

De acuerdo, pero eso no tiene que ver con el tema del hilo pues no requieres ese nivel de conocimientos para acceder a la memoria física bajo Güindos... de allí mi confusión.

La memoria caché no se "salta". Son accedidas a nivel hardware desde el principio.

De nuevo lo que comentaba anteriormente, no nos referimos a la memoria caché (fisica), si no a los métodos de caché que el SO utiliza.

Saludos

HySTD
30-08-2008, 03:21:20
Ok! para lo que se plantea, si tiene que ver el tema de la caché física, explicaré por qué.

El procesador, que genera direcciones virtuales y cuyo rango varía en función de su ancho del bus de direcciones, accede SIEMPRE a caché y no a RAM. A la RAM el procesador sólo accede cuando se producen fallos de caché, entonces el hardware realiza otro tipo de traducción de la dirección virtual a física (hemos supuesto que las caché son en la mayoría de los casos atacadas por direcciones virtuales del procesador), y quien se encarga de atacar a la memoria principal es el controlador (chipset puente norte), para adaptar temas de velocidad y ancho de bus.

Para la resolución al problema que se plantea, (sobre medir los tiempo de acceso medio a memoria, que es distinto a lo planteado al principio sobre llenar la RAM, en cuyo caso vuelvo a repetir sobre el diseño de un driver, para evitar paginación), hay que darse cuenta sólo de un pequeño detalle, y es en la penalización de tiempo que se produce cuando se da un fallo (el dato/instrucción no está en el nivel al que se accede), Y aquí es ahora donde está la clave: observar y comparar la penalización por fallo en los accesos.

Supón que haces un bucle largo, y realizas accesos a "memoria" (nos da igual si el dato está o no en caché, RAM o disco). Si el dato es de primera referencia se producirá un fallo forzoso en caché, con lo cual accederá a RAM, traduciendo la dirección virtual a física. Accede a ella y se trae un bloque o línea completo (por el tema de la localidad espacial), dicho bloque se almacena en caché, para en un segundo acceso al dato o al consecutivo (en el caso de un array o variable consecutiva), el dato ya estará en caché, consiguiendo reducir el tiempo de acceso. Del mismo modo, aunque con muchas más diferencias, ocurriria entre RAM y disco.

La cuestión por tanto, si queremos medir el tiempo en acceder a RAM , lo que tenemos que hacer es asegurar que SIEMPRE se van a producir fallos de caché (fallos de colisión o por conflictos). Para ello es necesario saber ¿Cuantos bytes ocupa cada linea de caché?. Como ésto es dificil de averiguar, lo normal es establecer un valor alto, y mediante un bucle ir incrementando no de 1 en 1, sino de "zancada+1" en "zancada+1", siendo "zancada" el valor estimado del tamaño de un bloque de la caché. Así se asegura un fallo.

Ahora bien, ¿Cuando sabremos que se está accediendo a caché y cuándo a RAM? Esto es fácil de ver utilizando por ejemplo la instrucción RDTSC de ensamblador (Read Time Stamp Counter), cuando observemos un aumento considerable (supondremos que en el bucle no hay interrupciones con otros procesos, cosa difícil de lograr), entonces se habrá accedido a un nivel inferior en la jerarquía de memoria (es decir de caché a RAM). La forma de proceder es exactamente igual que de RAM a disco.

Un saludo.

cHackAll
30-08-2008, 03:33:08
Interesante análisis HySTD, solo me quedan un par de dudas; que yo sepa como caché física solo tenemos la L1, L2... como podemos acceder a la misma mediante algun lenguaje?

...accede SIEMPRE a caché y no a RAM....

Quieres decir que hay la misma cantida de caché física que RAM? :confused:.. considerando la respuesta obvia tambien habria que medir la velocidad de transferencia de una a otra...

PD; no es que dude de ti, pero si es que voy a aprender algo nuevo te rogaría incluyas alguna referencia pues soy algo "esceptico". ;)

Saludos

kurono
30-08-2008, 05:11:09
amigos como dije anteriolmente estoy hablando de la memoria ram y solo quiero probar los tiempo de lectura/escritura nada mas y quiero saber como se puede hacer esto

HySTD
30-08-2008, 14:48:44
que yo sepa como caché física solo tenemos la L1, L2... como podemos acceder a la misma mediante algun lenguaje?


Repito, siempre que haya un acceso a memoria en una instrucción, se va a acceder a caché. De todas formas existen unos tipos de datos que fuerzan al compilador a que los datos permanezcan o no en caché (Los conozco en C, pero no se los homólogos en Delphi):


El Modificador register

Este modificador sobre una variable le indica al compilador que la variable debe almacenarse en un registro en el compilador, que para el caso de los IA32, es un registro real de la propia CPU, y por tanto el tiempo de acceso es más rápido respecto a la memoria RAM. Hoy en día a penas se utiliza este modificador, ya que los compiladores son capaces de determinar de manera óptima la asignación de registros a variables del programa.

El Modificador volatile

Al con otro valor, dicha variable se almacena directamente en memoria y no queda localizado el valor sólo en el registro de la CPU como pasaba en el casocontrario que el modificador registrer, volatile obliga al compilador a forzar el código resultante de manera que la variable modificada con este modificador, sea almacenada siempre en la memoria. El efecto que tiene es que cuando la variable se modifica de register o en condiciones normales. Un uso muy común en el que se suele emplear este modificador, es para acceder a variables que están siendo utilizadas por drivers o por periféricos, ya que si no declarásemos esta propiedad, podría darse el caso que la CPU usase el valor de la variable, por lo que la caché guarda el valor, y poco después la CPU usase de nuevo dicha variable, pero como ésta está en cache, la CPU coge el valor que existe en la caché, puede ser bien distinta si mientras un posible periférico ha modificado dicho valor.

Fuente: http://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Lo_m%C3%A1s_b%C3%A1sico#El_Modificador_volatile



Quieres decir que hay la misma cantida de caché física que RAM?

No! por supuesto que no. La diferencia radica en la decodificación de la dirección virtual que genera el procesador. El procesador genera una dirección virtual, pues bien, cuando se accede a caché se interpreta de una manera (Depende del tipo de caché: mapeado directo, asociativa por conjuntos o completamente asociativa), y cuando accede a RAM lo hace a través de una tabla de páginas (que puede estar almacenada en una caché especial: TLB) que contiene la dirección física que es concatenada con el desplazamiento de la dirección virtual.


amigos como dije anteriolmente estoy hablando de la memoria ram y solo quiero probar los tiempo de lectura/escritura nada mas y quiero saber como se puede hacer esto

Vuelvo a repetir, que tienes que basarte en la penalización por fallo entre un nivel y otro.

Si no te corre prisa, en cuanto tenga tiempo te pondré un código de ejemplo.

Un saludo.

coso
30-08-2008, 14:59:14
Mirando entonces de una manera practica : si se calcula el tiempo de acceso con una variable register, y luego este se resta de una variable sin este modificador con el mismo proceso, ¿entonces se tendria directamente el tiempo de acceso a RAM? creo q no hay equivalente de register ni de volatile en delphi, asi como de static si que se puede hacer un apaño. Igualmente, si lo que se quiere es medir el tiempo de acceso en global (cpu + mem) y no de la memoria en si, ¿que se tendria que hacer?

HySTD
30-08-2008, 15:52:08
Mirando entonces de una manera practica : si se calcula el tiempo de acceso con una variable register, y luego este se resta de una variable sin este modificador con el mismo proceso, ¿entonces se tendria directamente el tiempo de acceso a RAM?

Básicamente declarando como register, en teoria, deberías obtener el CPI de la instrucción que hace referencia a dicha variable.

si lo que se quiere es medir el tiempo de acceso en global (cpu + mem) y no de la memoria en si, ¿que se tendria que hacer?

Pues aplicar una formula muy simple:

Tiempo de acceso medio a memoria = Tiempo de acierto + (frecuencia de fallos * penalización por fallo)

Un saludo.

coso
30-08-2008, 15:56:38
lo siento, no domino mucho el tema de hardware...no se que es CPI ni tampoco sabia q podia "fallar" el acceso a memoria... ¿podrias poner un ejemplo? aunque fuese en c. Gracias de antemano.

coso
30-08-2008, 16:05:39
igualmente, pongo este (http://freespace.virgin.net/roy.longbottom/) link (y este (http://sourceforge.net/projects/opensourcemark))

HySTD
30-08-2008, 21:17:16
no se que es CPI

CPI = Ciclos por instrucción.

ni tampoco sabia q podia "fallar" el acceso a memoria

Pues si, de hecho se está constantemente fallando entre un nivel y otro de la jerarquía de memoria.

¿podrias poner un ejemplo? aunque fuese en c.

Por supuesto, o en Delphi también:

for i:=0 to 9 do begin
v[i]:=v[i]+1;
end;

en la primera referencia al primer elemento del vector "v" (v[0]), el procesador accede a caché, y el dato no se encuentra en ella, asi que se produce un fallo "forzoso". Debe acceder a RAM para buscarlo (Entonces aumenta el tiempo de acceso --> hay una penalización por fallo), supuesto el caso que alli se encuentra, se trae un bloque completo a caché, esto es, se traerá todos los elementos del vector a ésta. Cuando en el bucle se acceda a v[1], el elemento ya estará en caché con el consecuente resultado de una disminución de tiempo de acceso que si tuviese que ir a RAM. Del mismo modo ocurriría entre RAM y Disco; de hecho cuando ejecutas un programa (almacenado en disco), Tras la llamada a CreateProcess (para Windows), se logra cargar en RAM debido a los fallos: Si no se encuentra un dato requerido o solicitado por la CPU se busca en el siguiente nivel de la jerarquía, y se lo trae a un nivel más cercano (rápido) para la CPU, con una traducción distinta de las direcciones.

Bueno espero, con este hilo en general, haber aclarado algunos conceptos útiles para la programación a bajo nivel.

Un saludo.