\section{Resultados} \subsection{HSL} Los experimentos consisten en utilizar perf al correr los algoritmos HSL asm1, asm2 y C 100 veces para cada una de las im\'agenes del conjunto de prueba detallado en la introducci\'on para cada uno del siguiente conjunto de par\'ametros: (0, 0, 0); (70, 0, 1); (70, 1, 0); (80, 0.3, 0.3); (180, 0.5, 0.5); (360, 1, 1). Los resultados siguientes representan la cantidad de segundos que tardaron en ejecutarse estas 100 iteraciones de los algoritmos. \newline En primer lugar es fundamental determinar si un aumento en el tama\~no de las im\'agenes afecta a cada algoritmo (i.e. C, asm1, asm2) y a cada tupla de par\'ametros de entrada (e.g. (180, 0.5, 0.5)) de la misma forma. Para juzgar esto analizamos el tiempo de ejecuci\'on normalizado (es decir, el tiempo de ejecuci\'on [en segundos] de cada algoritmo dividido la cantidad de p\'ixeles de la imagen de entrada) en funci\'on de la cantidad de p\'ixeles de la imagen. Esta relaci\'on, con imagen de entrada monocrom\'atica azul y par\'ametros (0, 0, 0) se ve graficada en la imagen \ref{fig:hsl_chart1}. Si bien este gr\'afico representa solo una combinaci\'on de par\'ametros, para todos el resultado es el mismo: \textbf{el tama\~no de la imagen de entrada afecta de igual forma a los distintos algoritmos} para cada tupla de par\'ametros de entrada. Debido a esto, las conclusiones restantes las realizaremos a partir de un s\'olo tama\~no de imagen: 256x256 [pixeles]. \begin{figure}[htpb] \centering \caption{Tiempo de ejecuci\'on (en segundos) normalizado en funci\'on del tama\~no de la imagen} \label{fig:hsl_chart1} \includegraphics[width=0.75\columnwidth]{include/TiempoEjecucionNormalizadov2} \end{figure} Adicionalmente, queremos medir si im\'agenes de distintas proporciones pero igual tama\~no exhiben tiempos de ejecuci\'on similares. Para juzgar esto utilizaremos la siguiente f\'ormula: 100 * (max(m1, m2, m3) - min (m1, m2, m3)) / min (m1, m2, m3); donde m1, m2, m3 son el tiempo de ejecuci\'on del algoritmo para las distintas proporciones de una imagen. Los resultados obtenidos \textbf{indican que la diferencia en tiempo de ejecuci\'on no es significativa}; por ejemplo, para la imagen de color arbitrario, la diferencia para los algoritmos C, asm1 y asm2 son: 1.5799033719\%, 0.7088550664\%, 1.8452158231\%. \newline Tambi\'en quiere medir el impacto de los saltos condicionales en la eficacia del programa, para esto se observa el tiempo de ejecuci\'on para las im\'agenes monocromas (imagen \ref{fig:hsl_chart2}, con par\'ametros (0, 0, 0) e imagen \ref{fig:hsl_chart3}, con par\'ametros (180, 0.5, 0.5) ). En primer lugar se puede notar la significativa diferencia entre la imagen blanca y las dem\'as, en ambos casos; esto coincide con lo esperado, ya que al ser igual el m\'aximo que el m\'inimo (como es el caso del color blanco) se evitan gran cantidad de comparaciones y operaciones. En lo que respecta a los otros colores, se nota un significativo aumento en el tiempo de ejecuci\'on para el rojo, azul y random, mientras que se ve una reducci\'on para el verde. Una posible causa de esto es que en el caso del par\'ametro (180, 0.5, 0.5), se aumente el Hue correspondiente a esos 3 colores mientras que el del verde se reduce (al exceder 360 y ser truncado). \textbf{A mayor valor de Hue, m\'as operaciones se deben realizar antes del salto condicional, y por ende un exceso de 360 por parte del verde y no de los otros colores explicar\'ia esta diferencia}. \begin{figure}[htpb] \centering \caption{Tiempo de ejecuci\'on de im\'agenes mon\'ocromas para entrada (0, 0, 0)} \label{fig:hsl_chart2} \includegraphics[width=0.75\columnwidth]{include/DiferenciasPuro000} \end{figure} \begin{figure}[htpb] \centering \caption{Tiempo de ejecuci\'on de im\'agenes mon\'ocromas para entrada (180, 0.5, 0.5)} \label{fig:hsl_chart3} \includegraphics[width=0.75\columnwidth]{include/DiferenciasPuro180} \end{figure} Luego, se quiere analizar la diferencia entre im\'agenes de alto contraste e im\'agenes arbitrarias. El resultado de esta comparaci\'on, para par\'ametros (180, 0.5, 0.5), se encuentra en la imagen \ref{fig:hsl_chart4}. Se observa que la diferencia es virtualmente inexistente, confirmando por un lado que el alto contraste entre pixeles adyacentes no impacta sobre la eficacia de ninguno de los algoritmos (esto es esperable, ya que los tres iteran pixel por pixel), y que la potencial diferencia entre im\'agenes causado por saltos condicionales, previamente analizada, s\'olo parece hacer efecto en casos borde particulares (e.g. im\'agenes monocromas), pero tiene un efecto absolutamente despreciable en im\'agenes arbitrarias con alta diversidad de colores. \begin{figure}[htpb] \centering \caption{Tiempo de ejecuci\'on de im\'agenes arbitrarias y de alto contraste para entrada (180, 0.5, 0.5)} \label{fig:hsl_chart4} \includegraphics[width=0.75\columnwidth]{include/DiferenciasContrasteArbitraria} \end{figure} Finalmente, cabe destacar un resultado inesperado: en la abrumante mayor\'ia de los casos, el algoritmo C es m\'as r\'apido que el asm2, que es a su vez m\'as r\'apido que el asm1. Este resultado es extra\~no por dos razones: en primer lugar, se espera que los algoritmos de assembler sean m\'as eficientes que el de C; en segundo lugar, ya que el asm1 utiliza la misma suma que el asm2 y las transformaciones del C, de ser m\'as r\'apido este \'ultimo, se esperar\'ia que el asm1 resulte m\'as veloz que el asm2. Es posible que la superior eficiencia del C se deba a un uso \'optimo de registros en las operaciones y econom\'ia de m\'ascaras que permita evitar accesos innecesarios a memoria. A su vez, asm1 debe recurrir a un call a las funciones de transformaci\'on, y de acuerdo a la convenci\'on C los registros xmm no se preservan, por lo que no ver\'ia una mejora respecto del asm2 en ese caso. \FloatBarrier \pagebreak \subsection{Blur} A diferencia del filtro HSL la l\'ogica de procesamiento de ambas implementaciones del blur \textbf{no} depende del tipo de im\'agenes, por lo que se procedi\'o a realizar unas pruebas preliminares con distintas imagenes aleatorias y mon\'ocromas. Los tiempos de ejecuci\'on de dichas imagenes resultaron ser similar, habiendo peque\~nas diferencias aleatorias que se relacionaron con otras actividades que pudo haber estado realizando el sistema operativo. Por lo que se eligi\'o una de esas im\'agenes al azar para realizar el resto de las pruebas. Como se menciona en las hip\'otesis del blur, se puede observar que deb\'ido al calculo adicion\'al que realiza la implementaci\'on de \textbf{Blur 2} al momento de procesar las \'ultimas columnas de la imagen, en el cual se vuelven a procesar una cantidad de p\'ixeles que causa que en im\'agenes peque\~nas se obtenga un rendimiento similar a la implementaci\'on de \textbf{Blur 1} o \textbf{C}. En im\'agenes m\'as grandes ese procesamiento repetido se vuelve despreciable y se puede apreciar la ganancia de velocidad al realizar muchas menos operaciones de lectura. Se encontr\'o que en el caso de procesamiento de la im\'agen de $16x16$ el tiempo de ejecuci\'on fue generalmente mayor, se intent\'o buscar las causas de dicho comportamiento, pero solamente se pudo encontrar que las mismas no dependen, en general del algoritmo de procesamiento.%, sino del tiempo asignado por el CPU para la tarea. Esto es lo que causa que la desviaci\'on sea tan grande en este caso. En un principio resulta extra\~no el comportamiento de la implementaci\'on $1$, en la cual los tiempos dieron muy similares a los de la implementaci\'on \emph{C}, aunque la misma realiza menos lecturas de memoria. Deducimos, entonces, que debido a la cantidad de saltos condicionales que posee dicha implementaci\'on el procesador no puede realizar un manejo de prefetch \'optimo, provocando m\'as estados de espera. Mientras que en la implementaci\'on \emph{C} el compilador realiza optimizaciones y el procesamiento es m\'as secuencial, lo que puede aumentar su performance. En el resto de los casos el comportamiento es el esperado y solo var\'ia en funci\'on del tamaƱo de la imagen. Se conjetura entonces que el rendimiento de los algoritmos est\'a ligado a la cantidad de lecturas de memoria, y muy fuertemente a la cantidad de saltos condicionales en medio del procesamiento. En la figura \ref{fig:figure_blur} se puede observar los resultados de las pruebas realizadas con los diferentes tama\~nos de imagen. \begin{figure}[htpb] \centering \caption{Tiempo de ejecuci\'on de im\'agenes arbitrarias para el filtro blur } \label{fig:figure_blur} \includegraphics[width=0.75\columnwidth]{include/figure_blur} \end{figure} \FloatBarrier \subsection{Merge} En la primera prueba, para poder notar diferencias significativas, en los tests se modific\'o el c\'odigo de la aplicaci\'on para ejecutar 500 veces cada filtro, de esta manera se evita cargar nuevas instancias de los programas y calcular un tiempo incorrecto debido a la carga de d\'isco de las im\'agenes, cache de disco, la invocaci\'on de tareas, y se puede evaluar el uso de cache. Los tests se corrieron utilizando la herramienta \emph{perf} y obteniendo los datos de cache, instrucciones y otras operaciones para ayudar en la generaci\'on de las conclusiones. \\ Se utilizaron im\'agenes de diferentes tama\~nos para simular distintos casos y estudiar el comportamiento del filtro. Como el filtro no consiste, ni tiene l\'ogica que dependa del tipo de im\'agen (aleatoria, alto contraste, etc) nos basamos espec\'ificamente en tama\~nos. \\ Cada prueba se ejecut\'o 10 veces y se calcul\'o el promedio para el gr\'afico y la desviaci\'on est\'andar que se obtuvo. En cada ejecuci\'on se utiliz\'o un valor de merge de \emph{0, 0.13, 0.23, 0.33333, 0.4999, 0.5, 0.6542223, 0.75, 0.99999, 1} para probar los diferentes valores, pero se encontr\'o que no se obtienen cambos significantes al modificar dichos valores. En la figura \ref{fig:figure_blur} se puede observar los tiempos y resultados. \begin{figure}[htpb] \centering \caption{Tiempo de ejecuci\'on de im\'agenes arbitrarias, para el filtro merge con valores arbitrarios } \label{fig:figure_merge} \includegraphics[width=0.75\columnwidth]{include/figure_merge} \end{figure} En la mayor\'ia de los casos los cache-references rondaban el $75.0\%$ mientras que los cache-mises se mantenian menores a $0.05\%$. \\ Puede observarse lo que se hab\'ia predecido en la hip\'otesis, que los tiempos de ejecuci\'on comparados a la implementaci\'on \emph{C} son muchos menores en ambos casos de Assembler, posiblemente a la menor cantidad de lecturas de memoria. \\ Debido a que entra ambas implementaciones en Assembler poseen la misma cantidad de lecturas de memoria se puede conjeturar que la diferencia entre ambas implementaciones se debe a las operaciones extras de conversi\'on que se realiza en la implementaci\'on $1$ y a que se procesa de a 1 p\'ixel por instrucci\'on. En la implementaci\'on $2$ hay aproxim\'adamente un $20\%$ de instrucciones menos por p\'ixel a procesar que en la implementaci\'on $1$, hecho que puede observarse por los resultados. Se vi\'o que el tiempo de ejecuci\'on en una imagen de $512x512$ es mucho mayor que $1024x1024$, en especial en la implementaci\'on en C, viendo los datos del cache no pudimos llegar a la conclusi\'on de por que puede funcionar mas lento, ya que los valores son normales y consistentes con las imagenes de $128x128$ y $1024x1024$.