]> git.llucax.com Git - z.facultad/75.00/informe.git/commitdiff
Reorganizar flotantes para que queden mejor distribuidos
authorLeandro Lucarella <llucax@gmail.com>
Sat, 16 Oct 2010 05:50:57 +0000 (02:50 -0300)
committerLeandro Lucarella <llucax@gmail.com>
Sat, 16 Oct 2010 05:55:14 +0000 (02:55 -0300)
source/solucion.rst

index b19fd361b1f3ffc7a6c208cdb5018e333deb3d56..7cf64b77ebafebee46f270b08ff9401ce5f0ce9b 100644 (file)
@@ -2051,34 +2051,6 @@ En los casos donde se utilizan otro tipo de métricas para evaluar aspectos
 particulares sobre alguna modificación se describe como se realiza la medición
 donde se utiliza la métrica especial.
 
 particulares sobre alguna modificación se describe como se realiza la medición
 donde se utiliza la métrica especial.
 
-Variabilidad de los resultados entre ejecuciones
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Es de esperarse que haya una cierta variación en los resultados entre
-corridas, dada la indeterminación inherente a los sistemas operativos de
-tiempo compartido, que compiten por los recursos de la computadora.
-
-Para minimizar esta variación se utilizan varias herramientas. En primer
-lugar, se corren las pruebas estableciendo máxima prioridad (-19 en Linux_) al
-proceso utilizando el comando :manpage:`nice(1)`. La variación en la
-frecuencia del reloj los procesadores (para ahorrar energía) puede ser otra
-fuente de variación, por lo que se usa el comando :manpage:`cpufreq-set(1)`
-para establecer la máxima frecuencia disponible de manera fija.
-
-Sin embargo, a pesar de tomar estas precauciones, se sigue observando una
-amplia variabilidad entre corridas. Además se observa una variación más
-importante de la esperada no solo en el tiempo, también en el consumo de
-memoria, lo que es más extraño. Esta variación se debe principalmente a que
-Linux_ asigna el espacio de direcciones a los procesos con una componente
-azarosa (por razones de seguridad). Además, por omisión, la llamada al sistema
-:manpage:`mmap(2)` asigna direcciones de memoria altas primero, entregando
-direcciones más bajas en llamadas subsiguientes [LWN90311]_.
-
-El comando :manpage:`setarch(8)` sirve para controlar éste y otros aspectos de
-Linux_. La opción ``-L`` hace que se utilice un esquema de asignación de
-direcciones antiguo, que no tiene una componente aleatoria y asigna primero
-direcciones bajas. La opción ``-R`` solamente desactiva la componente azarosa
-al momento de asignar direcciones.
-
 .. flt:: t:sol-setarch
    :type: table
 
 .. flt:: t:sol-setarch
    :type: table
 
@@ -2134,35 +2106,6 @@ al momento de asignar direcciones.
       voronoi  0.001    0.000    0.000
       ======== ======== ======== ========
 
       voronoi  0.001    0.000    0.000
       ======== ======== ======== ========
 
-Ambas opciones, reducen notablemente la variación en los resultados (ver
-cuadro :vref:`t:sol-setarch`). Esto probablemente se debe a la naturaleza
-conservativa del recolector, dado que la probabilidad de tener *falsos
-positivos* depende directamente de los valores de las direcciones de memoria,
-aunque las pruebas en la que hay concurrencia involucrada, se siguen viendo
-grandes variaciones, que probablemente estén vinculadas a problemas de
-sincronización que se ven expuestos gracias al indeterminismo inherente a los
-programas multi-hilo.
-
-Si bien se obtienen resultados más estables utilizando un esquema diferente al
-utilizado por omisión, se decide no hacerlo dado que las mediciones serían
-menos realistas. Los usuarios en general no usan esta opción y se presentaría
-una visión más acotada sobre el comportamiento de los programas. Sin embargo,
-para evaluar el este efecto en los resultados, siempre que sea posible se
-analizan los resultados de un gran número de corridas observando
-principalmente su mínima, media, máxima y desvío estándar.
-
-
-
-Resultados para pruebas sintizadas
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A continuación se presentan los resultados obtenidos para las pruebas
-sintetizadas (ver :ref:`sol_bench_synth`). Se recuerda que este conjunto de
-resultados es útil para analizar ciertos aspectos puntuales de las
-modificaciones propuestas, pero en general distan mucho de como se comporta un
-programa real, por lo que los resultados deben ser analizados teniendo esto
-presente.
-
 .. flt:: fig:sol-bigarr-1cpu
 
    Resultados para ``bigarr`` (utilizando 1 procesador)
 .. flt:: fig:sol-bigarr-1cpu
 
    Resultados para ``bigarr`` (utilizando 1 procesador)
@@ -2202,6 +2145,86 @@ presente.
 
       .. image:: plots/pause-bigarr-1cpu.pdf
 
 
       .. image:: plots/pause-bigarr-1cpu.pdf
 
+Variabilidad de los resultados entre ejecuciones
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Es de esperarse que haya una cierta variación en los resultados entre
+corridas, dada la indeterminación inherente a los sistemas operativos de
+tiempo compartido, que compiten por los recursos de la computadora.
+
+Para minimizar esta variación se utilizan varias herramientas. En primer
+lugar, se corren las pruebas estableciendo máxima prioridad (-19 en Linux_) al
+proceso utilizando el comando :manpage:`nice(1)`. La variación en la
+frecuencia del reloj los procesadores (para ahorrar energía) puede ser otra
+fuente de variación, por lo que se usa el comando :manpage:`cpufreq-set(1)`
+para establecer la máxima frecuencia disponible de manera fija.
+
+Sin embargo, a pesar de tomar estas precauciones, se sigue observando una
+amplia variabilidad entre corridas. Además se observa una variación más
+importante de la esperada no solo en el tiempo, también en el consumo de
+memoria, lo que es más extraño. Esta variación se debe principalmente a que
+Linux_ asigna el espacio de direcciones a los procesos con una componente
+azarosa (por razones de seguridad). Además, por omisión, la llamada al sistema
+:manpage:`mmap(2)` asigna direcciones de memoria altas primero, entregando
+direcciones más bajas en llamadas subsiguientes [LWN90311]_.
+
+El comando :manpage:`setarch(8)` sirve para controlar éste y otros aspectos de
+Linux_. La opción ``-L`` hace que se utilice un esquema de asignación de
+direcciones antiguo, que no tiene una componente aleatoria y asigna primero
+direcciones bajas. La opción ``-R`` solamente desactiva la componente azarosa
+al momento de asignar direcciones.
+
+Ambas opciones, reducen notablemente la variación en los resultados (ver
+cuadro :vref:`t:sol-setarch`). Esto probablemente se debe a la naturaleza
+conservativa del recolector, dado que la probabilidad de tener *falsos
+positivos* depende directamente de los valores de las direcciones de memoria,
+aunque las pruebas en la que hay concurrencia involucrada, se siguen viendo
+grandes variaciones, que probablemente estén vinculadas a problemas de
+sincronización que se ven expuestos gracias al indeterminismo inherente a los
+programas multi-hilo.
+
+Si bien se obtienen resultados más estables utilizando un esquema diferente al
+utilizado por omisión, se decide no hacerlo dado que las mediciones serían
+menos realistas. Los usuarios en general no usan esta opción y se presentaría
+una visión más acotada sobre el comportamiento de los programas. Sin embargo,
+para evaluar el este efecto en los resultados, siempre que sea posible se
+analizan los resultados de un gran número de corridas observando
+principalmente su mínima, media, máxima y desvío estándar.
+
+
+
+Resultados para pruebas sintizadas
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A continuación se presentan los resultados obtenidos para las pruebas
+sintetizadas (ver :ref:`sol_bench_synth`). Se recuerda que este conjunto de
+resultados es útil para analizar ciertos aspectos puntuales de las
+modificaciones propuestas, pero en general distan mucho de como se comporta un
+programa real, por lo que los resultados deben ser analizados teniendo esto
+presente.
+
+``bigarr``
+^^^^^^^^^^
+En la figura :vref:`fig:sol-bigarr-1cpu` se pueden observar los resultados
+para ``bigarr`` al utilizar un solo procesador. En ella se puede notar que el
+tiempo total de ejecución en general aumenta al utilizar CDGC, esto es
+esperable, dado esta prueba se limitan a usar servicios del recolector. Dado
+que esta ejecución utiliza solo un procesador y por lo tanto no se puede sacar
+provecho a la concurrencia, es de esperarse que el trabajo extra realizado por
+las modificaciones se vea reflejado en los resultados. En la
+:vref:`fig:sol-bigarr-4cpu` (resultados al utilizar 4 procesadores) se puede
+observar como al usar solamente *eager allocation* se recupera un poco el
+tiempo de ejecución, probablemente debido al incremento en la concurrencia
+(aunque no se observa el mismo efecto al usar *early collection*).
+
+Observando el tiempo total de ejecución, no se esperaba un incremento tan
+notorio al pasar de TBGC a una configuración equivalente de CDGC **cons**,
+haciendo un breve análisis de las posibles causas, lo más probable parece ser
+el incremento en la complejidad de la fase de marcado dada capacidad para
+marcar de forma precisa (aunque no se use la opción, se paga el precio de la
+complejidad extra y sin obtener los beneficios).  Además se puede observar
+como el agregado de precisión al marcado mejora un poco las cosas (donde sí se
+obtiene rédito de la complejidad extra en el marcado).
+
 .. flt:: fig:sol-bigarr-4cpu
 
    Resultados para ``bigarr`` (utilizando 4 procesadores)
 .. flt:: fig:sol-bigarr-4cpu
 
    Resultados para ``bigarr`` (utilizando 4 procesadores)
@@ -2241,6 +2264,28 @@ presente.
 
       .. image:: plots/pause-bigarr-4cpu.pdf
 
 
       .. image:: plots/pause-bigarr-4cpu.pdf
 
+En general se observa que al usar *eager allocation* el consumo de memoria
+y los tiempos de pausa se disparan mientras que la cantidad de recolecciones
+disminuye drásticamente. Lo que se observa es que el programa es
+más veloz pidiendo memoria que recolectándola, por lo que crece mucho el
+consumo de memoria. Como consecuencia la fase de barrido (que no corre en
+paralelo al *mutator* como la fase de marcado) empieza a ser predominante en
+el tiempo de pausa por ser tan grande la cantidad de memoria a barrer. Este
+efecto se ve tanto al usar 1 como 4 procesadores, aunque el efecto es mucho
+más nocivo al usar 1 debido a la alta variabilidad que impone la competencia
+entre el *mutator* y recolector al correr de forma concurrente.
+
+Sin embargo, el tiempo de *stop-the-world* es siempre considerablemente más
+pequeño al utilizar marcado concurrente en CDGC, incluso cuando se utiliza
+*eager allocation*, aunque en este caso aumenta un poco, también debido al
+incremento en el consumo de memoria, ya que el sistema operativo tiene que
+copiar tablas de memoria más grandes al efectuar el *fork* (ver
+:ref:`sol_fork`).
+
+.. raw:: latex
+
+   \clearpage
+
 .. flt:: fig:sol-concpu-1cpu
 
    Resultados para ``concpu`` (utilizando 1 procesador)
 .. flt:: fig:sol-concpu-1cpu
 
    Resultados para ``concpu`` (utilizando 1 procesador)
@@ -2319,6 +2364,52 @@ presente.
 
       .. image:: plots/pause-concpu-4cpu.pdf
 
 
       .. image:: plots/pause-concpu-4cpu.pdf
 
+``concpu``
+^^^^^^^^^^
+En la figura :vref:`fig:sol-concpu-1cpu` se pueden observar los resultados
+para ``concpu`` al utilizar un solo procesador. En ella se aprecia que el
+tiempo total de ejecución disminuye levemente al usar marcado concurrente
+mientras no se utilice *eager allocation* pero aumenta al utilizarlo.
+
+Con respecto a la cantidad de recolecciones, uso máximo de memoria y tiempo de
+*stop-the-world* se ve un efecto similar al descripto para ``bigarr`` (aunque
+magnificado), pero sorprendentemente el tiempo total de pausa se dispara,
+además con una variabilidad sorprendente, cuando se usa marcado concurrente
+(pero no *eager allocation*). Una posible explicación podría ser que al
+realizarse el *fork*, el sistema operativo muy probablemente entregue el
+control del único procesador disponible al resto de los hilos que compiten por
+él, por lo que queda mucho tiempo pausado en esa operación aunque realmente no
+esté haciendo trabajo alguno (simplemente no tiene tiempo de procesador para
+correr). Este efecto se cancela al usar *eager allocation* dado que el
+*mutator* nunca se bloquea esperando que el proceso de marcado finalice.
+
+Además se observa una caída importante en la cantidad de recolecciones al
+utilizar marcado concurrente. Esto probablemente se deba a que solo un hilo
+pide memoria (y por lo tanto dispara recolecciones), mientras los demás hilos
+también estén corriendo. Al pausarse todos los hilos por menos tiempo, el
+trabajo se hace más rápido (lo que explica la disminución del tiempo total de
+ejecución) y son necesarias menos recolecciones, por terminar más rápido
+también el hilo que las dispara.
+
+En la :vref:`fig:sol-concpu-4cpu` se pueden ver los resultados al utilizar
+4 procesadores, donde el panorama cambia sustancialmente. El efecto mencionado
+en el párrafo anterior no se observa más (pues el sistema operativo tiene más
+procesadores para asignar a los hilos) pero todos los resultados se vuelven
+más variables. Los tiempos de *stop-the-world* y pausa real (salvo por lo
+recién mencionado) crecen notablemente, al igual que su variación. No se
+encuentra una razón evidente para esto; podría ser un error en la medición
+dado que al utilizar todos los procesadores disponibles del *hardware*,
+cualquier otro proceso que compita por tiempo de procesador puede afectarla
+más fácilmente.
+
+El tiempo total de ejecución crece considerablemente, como se espera, dado que
+el programa aprovecha los múltiples hilos que pueden correr en paralelo en
+procesadores diferentes.
+
+Sin embargo, no se encuentra una razón clara para explicar el crecimiento
+dramático en la cantidad de recolecciones solo al no usar marcado concurrente
+para 4 procesadores.
+
 .. flt:: fig:sol-conalloc-1cpu
 
    Resultados para ``conalloc`` (utilizando 1 procesador)
 .. flt:: fig:sol-conalloc-1cpu
 
    Resultados para ``conalloc`` (utilizando 1 procesador)
@@ -2436,6 +2527,48 @@ presente.
 
       .. image:: plots/pause-split-1cpu.pdf
 
 
       .. image:: plots/pause-split-1cpu.pdf
 
+``conalloc``
+^^^^^^^^^^^^
+En la figura :vref:`fig:sol-conalloc-1cpu` se pueden observar los resultados
+para ``conalloc`` al utilizar un solo procesador. Los cambios con respecto
+a lo observado para ``concpu`` son mínimos. El efecto de la mejoría al usar
+marcado concurrente pero no *eager allocation* no se observa más, dado que
+``conalloc`` pide memoria en todos los hilos, se crea un cuello de botella. Se
+ve claramente como tampoco baja la cantidad de recolecciones hecha debido
+a esto y se invierte la variabilidad entre los tiempos pico de pausa real
+y *stop-the-world* (sin una razón obvia, pero probablemente relacionado que
+todos los hilos piden memoria).
+
+Al utilizar 4 procesadores (figura :vref:`fig:sol-conalloc-4cpu`), más allá de
+las diferencias mencionadas para 1 procesador, no se observan grandes cambios
+con respecto a lo observado para ``concpu``, excepto que los tiempos de pausa
+(real y *stop-the-world*) son notablemente más pequeños, lo que pareciera
+confirmar un error en la medición de ``concpu``.
+
+``split``
+^^^^^^^^^
+Este es el primer caso donde se aprecia la sustancial mejora proporcionada por
+una pequeña optimización, el caché de ``findSize()`` (ver
+:ref:`sol_minor_findsize`). En la figura :vref:`fig:sol-split-1cpu` se puede
+observar con claridad como, para cualquier configuración de CDGC, hay una
+caída notable en el tiempo total de ejecución. Sin embargo, a excepción de
+cuando se utiliza *eager allocation*, la cantidad de recolecciones y memoria
+usada permanece igual.
+
+La utilización de *eager allocation* mejora (aunque de forma apenas
+apreciable) el tiempo de ejecución, la cantidad de recolecciones baja a un
+tercio y el tiempo de pausa real cae dramáticamente. Al usar marcado
+concurrente ya se observa una caída determinante en el tiempo de
+*stop-the-world*. Todo esto sin verse afectado el uso máximo de memoria,
+incluso al usar *eager allocation*.
+
+Se omiten los resultados para más de un procesador por ser prácticamente
+idénticos para este análisis.
+
+.. raw:: latex
+
+   \clearpage
+
 .. flt:: fig:sol-mcore-1cpu
 
    Resultados para ``mcore`` (utilizando 1 procesador)
 .. flt:: fig:sol-mcore-1cpu
 
    Resultados para ``mcore`` (utilizando 1 procesador)
@@ -2553,131 +2686,6 @@ presente.
 
       .. image:: plots/pause-rnddata-1cpu.pdf
 
 
       .. image:: plots/pause-rnddata-1cpu.pdf
 
-``bigarr``
-^^^^^^^^^^
-En la figura :vref:`fig:sol-bigarr-1cpu` se pueden observar los resultados
-para ``bigarr`` al utilizar un solo procesador. En ella se puede notar que el
-tiempo total de ejecución en general aumenta al utilizar CDGC, esto es
-esperable, dado esta prueba se limitan a usar servicios del recolector. Dado
-que esta ejecución utiliza solo un procesador y por lo tanto no se puede sacar
-provecho a la concurrencia, es de esperarse que el trabajo extra realizado por
-las modificaciones se vea reflejado en los resultados. En la
-:vref:`fig:sol-bigarr-4cpu` (resultados al utilizar 4 procesadores) se puede
-observar como al usar solamente *eager allocation* se recupera un poco el
-tiempo de ejecución, probablemente debido al incremento en la concurrencia
-(aunque no se observa el mismo efecto al usar *early collection*).
-
-Observando el tiempo total de ejecución, no se esperaba un incremento tan
-notorio al pasar de TBGC a una configuración equivalente de CDGC **cons**,
-haciendo un breve análisis de las posibles causas, lo más probable parece ser
-el incremento en la complejidad de la fase de marcado dada capacidad para
-marcar de forma precisa (aunque no se use la opción, se paga el precio de la
-complejidad extra y sin obtener los beneficios).  Además se puede observar
-como el agregado de precisión al marcado mejora un poco las cosas (donde sí se
-obtiene rédito de la complejidad extra en el marcado).
-
-En general se observa que al usar *eager allocation* el consumo de memoria
-y los tiempos de pausa se disparan mientras que la cantidad de recolecciones
-disminuye drásticamente. Lo que se observa es que el programa es
-más veloz pidiendo memoria que recolectándola, por lo que crece mucho el
-consumo de memoria. Como consecuencia la fase de barrido (que no corre en
-paralelo al *mutator* como la fase de marcado) empieza a ser predominante en
-el tiempo de pausa por ser tan grande la cantidad de memoria a barrer. Este
-efecto se ve tanto al usar 1 como 4 procesadores, aunque el efecto es mucho
-más nocivo al usar 1 debido a la alta variabilidad que impone la competencia
-entre el *mutator* y recolector al correr de forma concurrente.
-
-Sin embargo, el tiempo de *stop-the-world* es siempre considerablemente más
-pequeño al utilizar marcado concurrente en CDGC, incluso cuando se utiliza
-*eager allocation*, aunque en este caso aumenta un poco, también debido al
-incremento en el consumo de memoria, ya que el sistema operativo tiene que
-copiar tablas de memoria más grandes al efectuar el *fork* (ver
-:ref:`sol_fork`).
-
-``concpu``
-^^^^^^^^^^
-En la figura :vref:`fig:sol-concpu-1cpu` se pueden observar los resultados
-para ``concpu`` al utilizar un solo procesador. En ella se aprecia que el
-tiempo total de ejecución disminuye levemente al usar marcado concurrente
-mientras no se utilice *eager allocation* pero aumenta al utilizarlo.
-
-Con respecto a la cantidad de recolecciones, uso máximo de memoria y tiempo de
-*stop-the-world* se ve un efecto similar al descripto para ``bigarr`` (aunque
-magnificado), pero sorprendentemente el tiempo total de pausa se dispara,
-además con una variabilidad sorprendente, cuando se usa marcado concurrente
-(pero no *eager allocation*). Una posible explicación podría ser que al
-realizarse el *fork*, el sistema operativo muy probablemente entregue el
-control del único procesador disponible al resto de los hilos que compiten por
-él, por lo que queda mucho tiempo pausado en esa operación aunque realmente no
-esté haciendo trabajo alguno (simplemente no tiene tiempo de procesador para
-correr). Este efecto se cancela al usar *eager allocation* dado que el
-*mutator* nunca se bloquea esperando que el proceso de marcado finalice.
-
-Además se observa una caída importante en la cantidad de recolecciones al
-utilizar marcado concurrente. Esto probablemente se deba a que solo un hilo
-pide memoria (y por lo tanto dispara recolecciones), mientras los demás hilos
-también estén corriendo. Al pausarse todos los hilos por menos tiempo, el
-trabajo se hace más rápido (lo que explica la disminución del tiempo total de
-ejecución) y son necesarias menos recolecciones, por terminar más rápido
-también el hilo que las dispara.
-
-En la :vref:`fig:sol-concpu-4cpu` se pueden ver los resultados al utilizar
-4 procesadores, donde el panorama cambia sustancialmente. El efecto mencionado
-en el párrafo anterior no se observa más (pues el sistema operativo tiene más
-procesadores para asignar a los hilos) pero todos los resultados se vuelven
-más variables. Los tiempos de *stop-the-world* y pausa real (salvo por lo
-recién mencionado) crecen notablemente, al igual que su variación. No se
-encuentra una razón evidente para esto; podría ser un error en la medición
-dado que al utilizar todos los procesadores disponibles del *hardware*,
-cualquier otro proceso que compita por tiempo de procesador puede afectarla
-más fácilmente.
-
-El tiempo total de ejecución crece considerablemente, como se espera, dado que
-el programa aprovecha los múltiples hilos que pueden correr en paralelo en
-procesadores diferentes.
-
-Sin embargo, no se encuentra una razón clara para explicar el crecimiento
-dramático en la cantidad de recolecciones solo al no usar marcado concurrente
-para 4 procesadores.
-
-``conalloc``
-^^^^^^^^^^^^
-En la figura :vref:`fig:sol-conalloc-1cpu` se pueden observar los resultados
-para ``conalloc`` al utilizar un solo procesador. Los cambios con respecto
-a lo observado para ``concpu`` son mínimos. El efecto de la mejoría al usar
-marcado concurrente pero no *eager allocation* no se observa más, dado que
-``conalloc`` pide memoria en todos los hilos, se crea un cuello de botella. Se
-ve claramente como tampoco baja la cantidad de recolecciones hecha debido
-a esto y se invierte la variabilidad entre los tiempos pico de pausa real
-y *stop-the-world* (sin una razón obvia, pero probablemente relacionado que
-todos los hilos piden memoria).
-
-Al utilizar 4 procesadores (figura :vref:`fig:sol-conalloc-4cpu`), más allá de
-las diferencias mencionadas para 1 procesador, no se observan grandes cambios
-con respecto a lo observado para ``concpu``, excepto que los tiempos de pausa
-(real y *stop-the-world*) son notablemente más pequeños, lo que pareciera
-confirmar un error en la medición de ``concpu``.
-
-``split``
-^^^^^^^^^
-Este es el primer caso donde se aprecia la sustancial mejora proporcionada por
-una pequeña optimización, el caché de ``findSize()`` (ver
-:ref:`sol_minor_findsize`). En la figura :vref:`fig:sol-split-1cpu` se puede
-observar con claridad como, para cualquier configuración de CDGC, hay una
-caída notable en el tiempo total de ejecución. Sin embargo, a excepción de
-cuando se utiliza *eager allocation*, la cantidad de recolecciones y memoria
-usada permanece igual.
-
-La utilización de *eager allocation* mejora (aunque de forma apenas
-apreciable) el tiempo de ejecución, la cantidad de recolecciones baja a un
-tercio y el tiempo de pausa real cae dramáticamente. Al usar marcado
-concurrente ya se observa una caída determinante en el tiempo de
-*stop-the-world*. Todo esto sin verse afectado el uso máximo de memoria,
-incluso al usar *eager allocation*.
-
-Se omiten los resultados para más de un procesador por ser prácticamente
-idénticos para este análisis.
-
 ``mcore``
 ^^^^^^^^^
 El caso de ``mcore`` es interesante por ser, funcionalmente, una combinación
 ``mcore``
 ^^^^^^^^^
 El caso de ``mcore`` es interesante por ser, funcionalmente, una combinación
@@ -2743,10 +2751,6 @@ objetos grandes y otra objetos pequeños, pero esta diferencia parece no
 afectar la forma en la que se comportan los cambios introducidos en este
 trabajo.
 
 afectar la forma en la que se comportan los cambios introducidos en este
 trabajo.
 
-
-Resultados para pruebas pequeñas
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
 .. flt:: fig:sol-bh-1cpu
 
    Resultados para ``bh`` (utilizando 1 procesador)
 .. flt:: fig:sol-bh-1cpu
 
    Resultados para ``bh`` (utilizando 1 procesador)
@@ -2786,6 +2790,14 @@ Resultados para pruebas pequeñas
 
       .. image:: plots/pause-bh-1cpu.pdf
 
 
       .. image:: plots/pause-bh-1cpu.pdf
 
+.. raw:: latex
+
+   \clearpage
+
+
+Resultados para pruebas pequeñas
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
 A continuación se presentan los resultados obtenidos para las pruebas pequeñas
 (ver :ref:`sol_bench_small`). Se recuerda que si bien este conjunto de pruebas
 se compone de programas reales, que efectúan una tarea útil, están diseñados
 A continuación se presentan los resultados obtenidos para las pruebas pequeñas
 (ver :ref:`sol_bench_small`). Se recuerda que si bien este conjunto de pruebas
 se compone de programas reales, que efectúan una tarea útil, están diseñados
@@ -2811,12 +2823,6 @@ suspicacia.
    Preciso        302.54         472.26         169.72 (36%)
    ============== ============== ============== =================
 
    Preciso        302.54         472.26         169.72 (36%)
    ============== ============== ============== =================
 
-En la figura :vref:`fig:sol-bh-1cpu` se pueden observar los resultados
-para ``bh`` al utilizar un solo procesador. Ya en una prueba un poco más
-realista se puede observar el efecto positivo del marcado preciso, en especial
-en la cantidad de recolecciones efectuadas (aunque no se traduzca en un menor
-consumo de memoria).
-
 .. flt:: fig:sol-bisort-1cpu
 
    Resultados para ``bisort`` (utilizando 1 procesador)
 .. flt:: fig:sol-bisort-1cpu
 
    Resultados para ``bisort`` (utilizando 1 procesador)
@@ -2856,6 +2862,12 @@ consumo de memoria).
 
       .. image:: plots/pause-bisort-1cpu.pdf
 
 
       .. image:: plots/pause-bisort-1cpu.pdf
 
+En la figura :vref:`fig:sol-bh-1cpu` se pueden observar los resultados
+para ``bh`` al utilizar un solo procesador. Ya en una prueba un poco más
+realista se puede observar el efecto positivo del marcado preciso, en especial
+en la cantidad de recolecciones efectuadas (aunque no se traduzca en un menor
+consumo de memoria).
+
 Sin embargo se observa también un efecto nocivo del marcado preciso en el
 consumo de memoria que intuitivamente debería disminuir, pero crece, y de
 forma considerable (unas 3 veces en promedio). La razón de esta particularidad
 Sin embargo se observa también un efecto nocivo del marcado preciso en el
 consumo de memoria que intuitivamente debería disminuir, pero crece, y de
 forma considerable (unas 3 veces en promedio). La razón de esta particularidad
@@ -2867,6 +2879,36 @@ realmente asignada por el recolector (y la memoria desperdiciada) cuando se
 usa marcado conservativo y preciso. Estos valores fueron tomados usando la
 opción ``malloc_stats_file`` (ver :ref:`sol_stats`).
 
 usa marcado conservativo y preciso. Estos valores fueron tomados usando la
 opción ``malloc_stats_file`` (ver :ref:`sol_stats`).
 
+Más allá de esto, los resultados son muy similares a los obtenidos para
+pruebas sintetizadas que se limitan a ejercitar el recolector (como ``bigarr``
+y ``sbtree``), lo que habla de lo mucho que también lo hace este pequeño
+programa.
+
+No se muestran los resultados para más de un procesador por ser extremadamente
+similares a los obtenidos utilizando solo uno.
+
+``bisort``
+^^^^^^^^^^
+La figura :vref:`fig:sol-bisort-1cpu` muestra los resultados para ``bisort``
+al utilizar 1 procesador. En este caso el parecido es con los resultados para
+la prueba sintetizada ``split``, con la diferencia que el tiempo de ejecución
+total prácticamente no varía entre TBGC y CDGC, ni entre las diferentes
+configuraciones del último (evidentemente en este caso no se aprovecha el
+caché de ``findSize()``).
+
+Otra diferencia notable es la considerable reducción del tiempo de pausa real
+al utilizar *early collection* (más de 3 veces menor en promedio comparado
+a cuando se marca de forma conservativa, y más de 2 veces menor que cuando se
+hace de forma precisa), lo que indica que la predicción de cuando se va
+a necesitar una recolección es más efectiva que para ``split``.
+
+No se muestran los resultados para más de un procesador por ser extremadamente
+similares a los obtenidos utilizando solo uno.
+
+.. raw:: latex
+
+   \clearpage
+
 .. flt:: fig:sol-em3d-1cpu
 
    Resultados para ``em3d`` (utilizando 1 procesador)
 .. flt:: fig:sol-em3d-1cpu
 
    Resultados para ``em3d`` (utilizando 1 procesador)
@@ -2906,22 +2948,15 @@ opción ``malloc_stats_file`` (ver :ref:`sol_stats`).
 
       .. image:: plots/pause-em3d-1cpu.pdf
 
 
       .. image:: plots/pause-em3d-1cpu.pdf
 
-Más allá de esto, los resultados son muy similares a los obtenidos para
-pruebas sintetizadas que se limitan a ejercitar el recolector (como ``bigarr``
-y ``sbtree``), lo que habla de lo mucho que también lo hace este pequeño
-programa.
-
-No se muestran los resultados para más de un procesador por ser extremadamente
-similares a los obtenidos utilizando solo uno.
+``em3d``
+^^^^^^^^
+Los resultados para ``em3d`` (figura :vref:`fig:sol-em3d-1cpu`) son
+sorprendentemente similares a los de ``bisort``. La única diferencia es que en
+este caso el marcado preciso y el uso de *early collection** no parecen
+ayudar; por el contrario, aumentan levemente el tiempo de pausa real.
 
 
-``bisort``
-^^^^^^^^^^
-La figura :vref:`fig:sol-bisort-1cpu` muestra los resultados para ``bisort``
-al utilizar 1 procesador. En este caso el parecido es con los resultados para
-la prueba sintetizada ``split``, con la diferencia que el tiempo de ejecución
-total prácticamente no varía entre TBGC y CDGC, ni entre las diferentes
-configuraciones del último (evidentemente en este caso no se aprovecha el
-caché de ``findSize()``).
+Una vez más no se muestran los resultados para más de un procesador por ser
+extremadamente similares a los obtenidos utilizando solo uno.
 
 .. flt:: fig:sol-tsp-1cpu
 
 
 .. flt:: fig:sol-tsp-1cpu
 
@@ -2962,22 +2997,6 @@ caché de ``findSize()``).
 
       .. image:: plots/pause-tsp-1cpu.pdf
 
 
       .. image:: plots/pause-tsp-1cpu.pdf
 
-Otra diferencia notable es la considerable reducción del tiempo de pausa real
-al utilizar *early collection* (más de 3 veces menor en promedio comparado
-a cuando se marca de forma conservativa, y más de 2 veces menor que cuando se
-hace de forma precisa), lo que indica que la predicción de cuando se va
-a necesitar una recolección es más efectiva que para ``split``.
-
-No se muestran los resultados para más de un procesador por ser extremadamente
-similares a los obtenidos utilizando solo uno.
-
-``em3d``
-^^^^^^^^
-Los resultados para ``em3d`` (figura :vref:`fig:sol-em3d-1cpu`) son
-sorprendentemente similares a los de ``bisort``. La única diferencia es que en
-este caso el marcado preciso y el uso de *early collection** no parecen
-ayudar; por el contrario, aumentan levemente el tiempo de pausa real.
-
 .. flt:: fig:sol-voronoi-1cpu
 
    Resultados para ``voronoi`` (utilizando 1 procesador)
 .. flt:: fig:sol-voronoi-1cpu
 
    Resultados para ``voronoi`` (utilizando 1 procesador)
@@ -3056,9 +3075,6 @@ ayudar; por el contrario, aumentan levemente el tiempo de pausa real.
 
       .. image:: plots/pause-voronoi-4cpu.pdf
 
 
       .. image:: plots/pause-voronoi-4cpu.pdf
 
-Una vez más no se muestran los resultados para más de un procesador por ser
-extremadamente similares a los obtenidos utilizando solo uno.
-
 ``tsp``
 ^^^^^^^^
 Los resultados para ``tsp`` (figura :vref:`fig:sol-tsp-1cpu`) son
 ``tsp``
 ^^^^^^^^
 Los resultados para ``tsp`` (figura :vref:`fig:sol-tsp-1cpu`) son
@@ -3167,6 +3183,7 @@ utilizando CDGC con la opción ``min_free=0`` se obtiene una media del orden de
 los 80 segundos, bastante más alta que el tiempo obtenido para TBGC.
 
 .. flt:: fig:sol-dil-4cpu
 los 80 segundos, bastante más alta que el tiempo obtenido para TBGC.
 
 .. flt:: fig:sol-dil-4cpu
+   :placement: t
 
    Resultados para ``dil`` (utilizando 4 procesadores)
 
 
    Resultados para ``dil`` (utilizando 4 procesadores)
 
@@ -3216,6 +3233,7 @@ memoria desperdiciada entre el modo conservativo y preciso.
 
 .. flt:: t:sol-prec-mem-dil
    :type: table
 
 .. flt:: t:sol-prec-mem-dil
    :type: table
+   :placement: b
 
    Memoria pedida y asignada para ``dil`` según modo de marcado
 
 
    Memoria pedida y asignada para ``dil`` según modo de marcado