diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..682b0c7 Binary files /dev/null and b/.DS_Store differ diff --git a/T1/.DS_Store b/T1/.DS_Store new file mode 100644 index 0000000..7048fe3 Binary files /dev/null and b/T1/.DS_Store differ diff --git a/T1/Makefile b/T1/Makefile new file mode 100644 index 0000000..f946123 --- /dev/null +++ b/T1/Makefile @@ -0,0 +1,84 @@ +# Para revisar las opciones de compilacion y ejecucion, +# ingrese en el terminal el comando: make +# +# + +PROB=suma + +TEST=test-$(PROB) +HEADER=$(PROB) + +SHELL=bash -o pipefail + +INCLUDE= +CFLAGS=-Wall -Werror -std=c18 $(INCLUDE) +#CFLAGS=-Wall -Werror -pedantic -std=c18 $(INCLUDE) +LDLIBS=-lm -lpthread + +MAK=make --no-print-directory + +readme: + @less README.txt + +$(PROB).bin $(PROB).bin-g $(PROB).bin-san $(PROB).bin-thr: $(PROB).c $(TEST).c $(HEADER).h + +run-san: $(PROB).bin-san + @if grep -P '\t' $(PROB).c ; then echo "Su archivo $(PROB).c contiene tabs. Reemplacelos por espacios en blanco!" ; false ; else true; fi + ./$(PROB).bin-san + +run-thr: $(PROB).bin-thr + ./$(PROB).bin-thr + +run-g: $(PROB).bin-g + ./$(PROB).bin-g + +run: $(PROB).bin + ./$(PROB).bin + +ddd: $(PROB).ddd + +ddd-san: $(PROB).ddd-san + +zip: + @if grep -P '\t' $(PROB).c ; then echo "Su archivo $(PROB).c contiene tabs. Reemplacelos por espacios en blanco!" ; false ; else true; fi + @rm -f resultados.txt $(PROB).zip + @echo "Sistema operativo utilizado" > resultados.txt + @uname -a >> resultados.txt + @cat resultados.txt + @echo ==== run-san ==== | tee -a resultados.txt + @$(MAK) -B run-san | tee -a resultados.txt + @echo ==== run-thr ==== | tee -a resultados.txt + @$(MAK) -B run-thr | tee -a resultados.txt + @echo ==== run-g ==== | tee -a resultados.txt + @$(MAK) -B run-g | tee -a resultados.txt + @echo ==== run ==== | tee -a resultados.txt + @$(MAK) -B run | tee -a resultados.txt + @echo ==== zip ==== + zip -r $(PROB).zip resultados.txt $(PROB).c + @echo "Entregue por u-cursos el archivo $(PROB).zip" + @echo "Descargue de u-cursos lo que entrego, descargue nuevamente los" + @echo "archivos adjuntos y vuelva a probar la tarea tal cual como" + @echo "la entrego. Esto es para evitar que Ud. reciba un 1.0 en su" + @echo "tarea porque entrego los archivos equivocados. Creame, sucede" + @echo "a menudo por ahorrarse esta verificacion." + +%.bin: %.c + gcc -O -DOPT=1 $(CFLAGS) $^ $(LDLIBS) -o $@ + +%.bin-g: %.c + gcc -g $(CFLAGS) $^ $(LDLIBS) -o $@ + +%.bin-san: %.c + gcc -g -DSAN=1 -fsanitize=address -fsanitize=undefined $(CFLAGS) $^ $(LDLIBS) -o $@ + +%.bin-thr: %.c + gcc -g -DSAN=1 -fsanitize=thread -fsanitize=undefined $(CFLAGS) $^ $(LDLIBS) -o $@ + +%.ddd: %.bin-g + ddd $(*F).bin-g & + +%.ddd-san: %.bin-san + ddd $(*F).bin-san & + +clean: + rm -f *.o *.log *.bin* core diff --git a/T1/README.txt b/T1/README.txt new file mode 100644 index 0000000..d4d721d --- /dev/null +++ b/T1/README.txt @@ -0,0 +1,92 @@ +========================================================== +Esta es la documentación para compilar y ejecutar su tarea +========================================================== + +Se está ejecutando el comando: less README.txt + +*************************** +*** Para salir: tecla q *** +*************************** + +Para avanzar a una nueva página: tecla +Para retroceder a la página anterior: tecla +Para avanzar una sola línea: tecla +Para buscar un texto: tecla / seguido del texto (/...texto...) + por ejemplo: /ddd + +----------------------------------------------- + +Ud. debe crear el archivo suma.c y reprogramar ahí la función buscar. +Ya hay una plantilla para suma.c en suma.c.plantilla. + +Pruebe su tarea bajo Debian 13 de 64 bits. Estos son los requerimientos +para aprobar su tarea: + ++ make run-san debe felicitarlo y no reportar ningún incidente en el + manejo de memoria. + ++ make run-thr debe felicitarlo y no reportar ningún datarace + ++ make run debe felicitarlo por aprobar este modo de ejecución. + El speed up reportado debe ser de al menos 1.5. + ++ make run-g debe felicitarlo. + +Cuando pruebe su tarea con make run en su notebook asegúrese de que +posea al menos 2 cores, que está configurado en modo alto rendimiento +y que no estén corriendo otros procesos intensivos en uso de CPU al +mismo tiempo. De otro modo podría no lograr el speed up solicitado. + +Invoque el comando make zip para ejecutar todos los tests y generar un +archivo suma.zip que contiene suma.c, con su solución, y resultados.txt, +con la salida de make run, make run-g, make run-thr y make run-san. + +Para depurar use: make ddd + +Video con ejemplos de uso de ddd: https://youtu.be/FtHZy7UkTT4 +Archivos con los ejemplos: https://www.u-cursos.cl/ingenieria/2020/2/CC3301/1/novedades/r/demo-ddd.zip + +----------------------------------------------- + +Entrega de la tarea + +Ejecute: make zip + +Entregue por U-cursos el archivo suma.zip + +A continuación es muy importante que descargue de U-cursos el mismo +archivo que subió, luego descargue nuevamente los archivos adjuntos y +vuelva a probar la tarea tal cual como la entregó. Esto es para +evitar que Ud. reciba un 1.0 en su tarea porque entregó los archivos +equivocados. Creame, sucede a menudo por ahorrarse esta verificación. + +----------------------------------------------- + +Limpieza de archivos + +make clean + +Hace limpieza borrando todos los archivos que se pueden volver +a reconstruir a partir de los fuentes: *.o binarios etc. + +----------------------------------------------- + +Acerca del comando make + +El comando make sirve para automatizar el proceso de compilación asegurando +recompilar el archivo binario ejecutable cuando cambió uno de los archivos +fuentes de los cuales depende. + +A veces es útil usar make con la opción -n para que solo muestre +exactamente qué comandos va a ejecutar, sin ejecutarlos de verdad. +Por ejemplo: + + make -n sort-rv-nbits.ddd + +También es útil usar make con la opción -B para forzar la recompilación +de los fuentes a pesar de que no han cambiado desde la última compilación. +Por ejemplo: + + make -B sort-rv-nbits + +Recompilará para generar el archivo sort-rv-nbits desde cero diff --git a/T1/suma.c b/T1/suma.c new file mode 100644 index 0000000..b6368cb --- /dev/null +++ b/T1/suma.c @@ -0,0 +1,90 @@ +#include +#include + +#include "suma.h" + +enum { NTHREADS = 8 }; + +typedef struct { + int *a; + int n; + Set start; + Set end; + Set found; +} BuscarArgs; + +static Set total_combinaciones(int n) { + if (n >= (int)(sizeof(Set) * CHAR_BIT)) + return ~(Set)0; + return ((Set)1 << n) - 1; +} + +static Set buscar_rango(int a[], int n, Set start, Set end) { + if (start == 0 || start > end) + return 0; + + Set k = start; + while (1) { + long long sum = 0; + + for (int i = 0; i < n; i++) { + if (k & ((Set)1 << i)) + sum += a[i]; + } + + if (sum == 0) + return k; + + if (k == end) + break; + k++; + } + + return 0; +} + +static void *buscar_thread(void *ptr) { + BuscarArgs *args = ptr; + args->found = buscar_rango(args->a, args->n, args->start, args->end); + return NULL; +} + +Set buscar(int a[], int n) { + Set comb = total_combinaciones(n); + Set base = comb / NTHREADS; + Set extra = comb % NTHREADS; + Set next = 1; + pthread_t tids[NTHREADS]; + BuscarArgs args[NTHREADS]; + int created = 0; + + for (int t = 0; t < NTHREADS; t++) { + Set len = base + (Set)(t < (int)extra); + + args[t].a = a; + args[t].n = n; + args[t].start = next; + args[t].end = (len == 0) ? next - 1 + : (t == NTHREADS - 1 ? comb : next + len - 1); + args[t].found = 0; + + if (len != 0) + next = args[t].end + 1; + + if (pthread_create(&tids[t], NULL, buscar_thread, &args[t]) != 0) { + for (int i = 0; i < created; i++) + pthread_join(tids[i], NULL); + return buscar_rango(a, n, 1, comb); + } + created++; + } + + Set best = 0; + for (int t = 0; t < NTHREADS; t++) { + pthread_join(tids[t], NULL); + if (args[t].found != 0 && (best == 0 || args[t].found < best)) + best = args[t].found; + } + + return best; +} diff --git a/T1/suma.c.plantilla b/T1/suma.c.plantilla new file mode 100644 index 0000000..ea2a4d6 --- /dev/null +++ b/T1/suma.c.plantilla @@ -0,0 +1,15 @@ +#include +#include "suma.h" + +// Defina aca las estructuras que necesite + +... complete ... + +// Defina aca la funcion que ejecutaran los threads + +... complete ... + +// Reprograme aca la funcion buscar +Set buscar(int a[], int n) { +... complete ... +} diff --git a/T1/suma.h b/T1/suma.h new file mode 100644 index 0000000..01ee3d1 --- /dev/null +++ b/T1/suma.h @@ -0,0 +1,4 @@ +typedef unsigned long long Set; + +Set buscar(int a[], int n); + diff --git a/T1/suma.manual.bin b/T1/suma.manual.bin new file mode 100755 index 0000000..af7de6d Binary files /dev/null and b/T1/suma.manual.bin differ diff --git a/T1/suma.manual.san b/T1/suma.manual.san new file mode 100755 index 0000000..5b1805d Binary files /dev/null and b/T1/suma.manual.san differ diff --git a/T1/suma.manual.san.dSYM/Contents/Info.plist b/T1/suma.manual.san.dSYM/Contents/Info.plist new file mode 100644 index 0000000..46e2f8d --- /dev/null +++ b/T1/suma.manual.san.dSYM/Contents/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.apple.xcode.dsym.suma.manual.san + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + dSYM + CFBundleSignature + ???? + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/T1/suma.manual.san.dSYM/Contents/Resources/DWARF/suma.manual.san b/T1/suma.manual.san.dSYM/Contents/Resources/DWARF/suma.manual.san new file mode 100644 index 0000000..d305d0f Binary files /dev/null and b/T1/suma.manual.san.dSYM/Contents/Resources/DWARF/suma.manual.san differ diff --git a/T1/suma.manual.san.dSYM/Contents/Resources/Relocations/aarch64/suma.manual.san.yml b/T1/suma.manual.san.dSYM/Contents/Resources/Relocations/aarch64/suma.manual.san.yml new file mode 100644 index 0000000..25d33d9 --- /dev/null +++ b/T1/suma.manual.san.dSYM/Contents/Resources/Relocations/aarch64/suma.manual.san.yml @@ -0,0 +1,5 @@ +--- +triple: 'arm64-apple-darwin' +binary-path: suma.manual.san +relocations: [] +... diff --git a/T1/suma.manual.thr b/T1/suma.manual.thr new file mode 100755 index 0000000..f0ebe74 Binary files /dev/null and b/T1/suma.manual.thr differ diff --git a/T1/suma.manual.thr.dSYM/Contents/Info.plist b/T1/suma.manual.thr.dSYM/Contents/Info.plist new file mode 100644 index 0000000..e0790c6 --- /dev/null +++ b/T1/suma.manual.thr.dSYM/Contents/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.apple.xcode.dsym.suma.manual.thr + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + dSYM + CFBundleSignature + ???? + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/T1/suma.manual.thr.dSYM/Contents/Resources/DWARF/suma.manual.thr b/T1/suma.manual.thr.dSYM/Contents/Resources/DWARF/suma.manual.thr new file mode 100644 index 0000000..d97a073 Binary files /dev/null and b/T1/suma.manual.thr.dSYM/Contents/Resources/DWARF/suma.manual.thr differ diff --git a/T1/suma.manual.thr.dSYM/Contents/Resources/Relocations/aarch64/suma.manual.thr.yml b/T1/suma.manual.thr.dSYM/Contents/Resources/Relocations/aarch64/suma.manual.thr.yml new file mode 100644 index 0000000..71e4f99 --- /dev/null +++ b/T1/suma.manual.thr.dSYM/Contents/Resources/Relocations/aarch64/suma.manual.thr.yml @@ -0,0 +1,5 @@ +--- +triple: 'arm64-apple-darwin' +binary-path: suma.manual.thr +relocations: [] +... diff --git a/T1/test-suma.c b/T1/test-suma.c new file mode 100644 index 0000000..ef3522c --- /dev/null +++ b/T1/test-suma.c @@ -0,0 +1,176 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "suma.h" + +#ifdef OPT +#define N_INTENTOS 4 +#define TOLERANCIA 1.5 +#else +#define N_INTENTOS 1 +#define TOLERANCIA 0.01 +#endif + + +// ---------------------------------------------------- +// Funcion que entrega el tiempo transcurrido desde el lanzamiento del +// programa en milisegundos + +static int time0= 0; + +static int getTime0() { + struct timeval Timeval; + gettimeofday(&Timeval, NULL); + return Timeval.tv_sec*1000+Timeval.tv_usec/1000; +} + +void resetTime() { + time0= getTime0(); +} + +int getTime() { + return getTime0()-time0; +} + +// ---------------------------------------------------- + +Set buscarSeq(int a[], int n) { + Set comb= (1<<(n-1)<<1)-1; // 2n-1: nro. de combinaciones + for (Set k= 1; k<=comb; k++) { + // k es el mapa de bits para el subconjunto { a[i] | bit ki de k es 1 } + long long sum= 0; + for (int i= 0; i=TOLERANCIA) + break; + } + if (i>=N_INTENTOS) { + fprintf(stderr, "Despues de %d intentos no obtuvo un speedup de %f\n", + N_INTENTOS, TOLERANCIA); + fprintf(stderr, "Revise la paralelizacion.\n"); + exit(1); + } + printf("test 1 aprobado: speedup >= %f\n", TOLERANCIA); + printf("\n--------------------------------------------------\n\n"); + + printf("Uno ejemplo muy grande con n=29, con solucion\n"); + int c[]= { -3, -2, 5, + 122737, -37364, 287373, 27267, 967923, -25383, 924973, -28973, + 278363, 28272, 98734, -26735, 983267, 674998, 72537, 116725, + 72537, 27263, 82739, 829276, 5383715, 675483, -28334, 38495, + 374943, 278367}; + + printf("Calculando secuencialmente 2 veces\n"); + resetTime(); + k= buscarSeq(c, 29); + tiempo_sec= getTime(); + mostrar(c, k, 29); + printf("Tiempo secuencial= %d milisegundos\n", tiempo_sec); + + printf("Calculando en paralelo\n"); + resetTime(); + int k29= buscar(c, 29); + if (k!=k29) { + printf("Solucion incorrecta:\n"); + mostrar(c, k29, 29); + printf("Debio ser:\n"); + mostrar(c, k, 29); + exit(1); + } + tiempo_par= getTime(); + speedUp= (double)tiempo_sec/tiempo_par; + printf("buscar par tiempo= %d miliseg., speedup= %f\n", tiempo_par, speedUp); + printf("No se preocupe. Es normal que la version paralela se demore\n" + "mucho mas. Pero piense por que.\n\n"); + + printf("Felicitaciones: su tarea funciona\n"); + + return 0; +} +