\section{Detalles de las implementaciones y la generación de datos}\label{implementaciones}
Se describen a continuación todas las aplicaciones desarrolladas, la estructura de las mismas, el modo de uso, los datos que reciben como entrada y los que generan como salida, el procesamiento de toda esta información para producir los datos de las experiencias, y los \emph{scripts} empleados para automatizar las tareas.

\subsection{Estructura y modo de uso de los programas implementados}
Como ya fue descripto al comienzo de este documento, el trabajo consistió en tres proyectos: la experiencia correspondiente a la primera optimización algorítimica (\emph{Loop Unrolling}), y las experiencias asociadas al análisis de los algoritmos SHA-1 y SHA-256, respectivamente.

Los programas implementados para cada una de esas experiencias consisten en un módulo principal escrito en lenguaje \emph{C}, desde el cual se invocan a los otros módulos que implementan la distintas versiones de los algoritmos.

Por ejemplo, en el caso de la experiencia SHA-1, el módulo principal es \texttt{sha1.c}, y los módulos que implementan al algoritmo en versión escalar (en ensamblador y en \emph{C}), y en versión vectorizada (\emph{SIMD} en ensamblador) son, respectivamente, \texttt{sha1\_asm.asm}, \texttt{sha1\_c.c} y \texttt{sha1\_simd.asm}.

Todos estos proyectos, junto a los respectivos archivos, se encuentran organizados adecuadamente en directorios. Además, cada aplicación incluye el archivo \texttt{makefile} correspondientes. Las compilaciones realizadas con \texttt{gcc} incluye la optimización de máximo nivel (opción \texttt{-O3}).

A continuación se describen los datos de cada proyecto y el modo de cada programa:

\begin{enumerate}
\item Experiencia \emph{Loop Unrolling}:

\begin{itemize}
\item Ruta: \texttt{fuentes/sha1/sha1\_c\_vs\_c/}
\item Nombre del ejecutable: \texttt{sha1}
\item Modo de uso:

\vspace{5pt}
\texttt{./sha1 -opción ruta\_absoluta\_al\_archivo}

\vspace{5pt}
donde opción puede ser:
\begin{itemize}
\item[] \texttt{n}: ejecuta la versión \emph{normal} (esto es, sin \emph{loop unrolling}) del algoritmo SHA-1.
\item[] \texttt{u}: ejecuta la versión \emph{optimizada} con \emph{loop unrolling} del algoritmo SHA-1.
\end{itemize}

\vspace{5pt}
\item Ejemplo:

\vspace{5pt}
\texttt{./sha1\_c\_vs\_c -u /home/pedrito/un\_archivo.dat}
\vspace{5pt}

\end{itemize}

\vspace{3pt}
\item Experiencia \emph{SHA-1}:
\begin{itemize}
\item Ruta: \texttt{fuentes/sha1/sha1/}
\item Nombre del ejecutable: \texttt{sha1}
\item Modo de uso:

\vspace{5pt}
\texttt{./sha1 -opción ruta\_absoluta\_al\_archivo}

\vspace{5pt}
donde opción puede ser:
\begin{itemize}
\item[] \texttt{a}: ejecuta la versión escalar en ensamblador del algoritmo SHA-1.
\item[] \texttt{c}: ejecuta la versión escalar en C del algoritmo SHA-1.
\item[] \texttt{s}: ejecuta la versión vectorizada en ensamblador (\emph{SIMD}) del algoritmo SHA-1.
\end{itemize}

\vspace{5pt}
\item Ejemplo:

\vspace{5pt}
\texttt{./sha1 -s /home/pedrito/otro\_archivo.dat}
\vspace{5pt}
\end{itemize}

\vspace{3pt}
\item Experiencia \emph{SHA-256}:
\begin{itemize}
\item Ruta: \texttt{fuentes/sha256/}
\item Nombre del ejecutable: \texttt{sha256}
\item Modo de uso:

\vspace{5pt}
\texttt{./sha1 -opción ruta\_absoluta\_al\_archivo}

\vspace{5pt}
donde opción puede ser:
\begin{itemize}
\item[] \texttt{a}: ejecuta la versión escalar en ensamblador del algoritmo SHA-256.
\item[] \texttt{s}: ejecuta la versión vectorizada en ensamblador (\emph{SIMD}) del algoritmo SHA-256.
\end{itemize}

\vspace{5pt}
\item Ejemplo:

\vspace{5pt}
\texttt{./sha256 -s /home/pedrito/otro\_archivo\_mas.dat}
\vspace{5pt}
\end{itemize}
\end{enumerate}

La ejecución de cada uno de estos programas tiene como resultado la impresión del valor de hash correspondiente, el tamaño del archivo procesado, el tiempo de CPU en segundos, y el nombre del archivo de salida generado. La figura \ref{sha256_salida} muestra la salida para la aplicación \texttt{sha256}, empleando la versión vectorizada:

\begin{figure}[!ht]
\centering
\begin{verbatim}
 - Cálculo de hash SHA-256 mediante implementación vectorizada en ASM con SIMD:

   da87281c9f9ab6cef8f9362935f4fc864db94606d52212614894f1253461a762

 - Tiempo de CPU (en segs): 4.780000
 - Tamaño del archivo: 1048576000B
 - Salida agregada al archivo 'sha256_simd_out.dat'
\end{verbatim}
\caption{salida de ejemplo de la aplicación \texttt{sha256}}\label{sha256_salida}
\end{figure}

Los datos en el archivo de salida incluye al tamaño del archivo procesado y el tiempo de CPU en segundos que fueron requeridos para computar el valor de hash; ambos campos se separan mediante un \emph{;}. Si un archivo de salida ya existe, los datos se agregan al final.

Las distintas implementaciones para un algoritmo determinado generan archivos de salida diferentes. Por ejemplo, en el caso del algoritmo SHA-1, las ejecuciones con las opciones \texttt{a}, \texttt{c} y \texttt{s} generan, respectivamente, los siguientes archivos de salida: \texttt{sha1\_asm.out}, \texttt{sha1\_c.out} y \texttt{sha1\_simd.out}.

\subsection{Generación y procesamiento de los datos}
Para automatizar el proceso de generación de archivos, ejecución de las aplicaciones y procesamiento de los datos de salida correspondientes a cada experiencia, empleamos \emph{scripts} para \emph{Bash}. El conjunto de estas herramientas, junto a los archivos generados, puede encontrarse en el directorio \texttt{experiencias}.

Si bien cada proyecto (\emph{Loop Unrolling}, SHA-1 y SHA-256) incluye su propio \emph{script} para la generación y procesamiento automático de los datos de salida, se incluye también un \emph{script} general que ejecuta la totalidad de las experiencias en un solo paso. Se trata del \emph{script} \texttt{ejecutar\_experiencias.sh}, ubicado en el mencionado directorio \texttt{experiencias}.

En concreto, los \emph{scripts} generan para cada experiencia archivos temporales que varían en tamaño desde $0.5$ \emph{GB} a $3.0$ \emph{GB} en saltos de $0.5$ \emph{GB}. Eso da un total de 6 archivos de tamaños $0.5$ \emph{GB}, $1.0$ \emph{GB}, $1.5$ \emph{GB}, $2.0$ \emph{GB}, $2.5$ \emph{GB} y $3.0$ \emph{GB}, respectivamente. Estos archivos se generan de a uno por vez, y sobre cada uno de ellos se ejecutan los algoritmos, con sus distintas implementaciones, media docena de veces. Todos y cada uno de estos archivos temporales son eliminados automáticamente cuando finaliza el procesamiento de los datos correspondientes.

Puesto que los \emph{scripts} para \emph{Bash} carecen de capacidad para operar con valores flotantes (requeridos para manipular los tiempos de CPU, los promedios, etc.), los datos generados son procesados por separado en \emph{Excel}.

Se incluyen, por lo tanto, el volcado de estos datos en las distintas planillas de \emph{Excel} asociadas a cada experiencia. En estas planillas se computan promedios, ventajas en términos de porcentajes de una implementación con respecto a otra, gráficos, etc. Las planillas se encuentran en el subdirectorio \texttt{Datos procesados (Excel)} de \texttt{experiencias}, separadas, a su vez, en otros directorios que se distinguen por el nombre de los algoritmos analizados.



