add files

This commit is contained in:
2026-03-24 15:51:42 -03:00
parent 0c7fb66607
commit 9dc9f3827e
17 changed files with 511 additions and 0 deletions

BIN
T1/.DS_Store vendored Normal file

Binary file not shown.

84
T1/Makefile Normal file
View File

@@ -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

92
T1/README.txt Normal file
View File

@@ -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 <page down>
Para retroceder a la página anterior: tecla <page up>
Para avanzar una sola línea: tecla <enter>
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

90
T1/suma.c Normal file
View File

@@ -0,0 +1,90 @@
#include <limits.h>
#include <pthread.h>
#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;
}

15
T1/suma.c.plantilla Normal file
View File

@@ -0,0 +1,15 @@
#include <pthread.h>
#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 ...
}

4
T1/suma.h Normal file
View File

@@ -0,0 +1,4 @@
typedef unsigned long long Set;
Set buscar(int a[], int n);

BIN
T1/suma.manual.bin Executable file

Binary file not shown.

BIN
T1/suma.manual.san Executable file

Binary file not shown.

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.suma.manual.san</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

View File

@@ -0,0 +1,5 @@
---
triple: 'arm64-apple-darwin'
binary-path: suma.manual.san
relocations: []
...

BIN
T1/suma.manual.thr Executable file

Binary file not shown.

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.suma.manual.thr</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

View File

@@ -0,0 +1,5 @@
---
triple: 'arm64-apple-darwin'
binary-path: suma.manual.thr
relocations: []
...

176
T1/test-suma.c Normal file
View File

@@ -0,0 +1,176 @@
#include <stdio.h>
#include <pthread.h>
#include <math.h>
#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#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<n; i++) {
if ( k & ((Set)1<<i) ) // si bit ki de k es 1
sum+= a[i];
}
if (sum==0) { // exito: el subconjunto suma 0
return k; // y el mapa de bits para el subconjunto es k
} }
return 0; // no existe subconjunto que sume 0
}
void mostrar(int a[], Set k, int n) {
long long sum= 0;
if (k==0) {
printf("subconjunto no existe\n");
return;
}
for (int i= 0; i<n; i++) {
if ( k & ((Set)1<<i) ) {
printf("%d ", a[i]);
sum+= a[i];
}
}
if (sum!=0) {
fprintf(stderr, "El subconjunto suma %lld, no 0\n", sum);
}
printf("\n");
}
#define N 10000
#define M 20000
#define P 4
int main() {
printf("Test 1: El ejemplo del enunciado\n");
int a[]= { -7, -3, -2, 5, 8};
Set kSeq= buscarSeq(a, 5);
mostrar(a, kSeq, 5);
Set k= buscar(a, 5);
if (k!=kSeq) {
fprintf(stderr, "La solucion debio ser %lld, no %lld\n", kSeq, k);
exit(1);
}
mostrar(a, k, 5);
printf("test 1 aprobado\n");
printf("\n--------------------------------------------------\n\n");
printf("Test 2: Uno ejemplo mas grande con n=26, sin solucion\n");
int b[]= { 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};
int tiempo_sec, tiempo_par;
double speedUp= 0;
int i;
printf("Calculando secuencialmente 2 veces\n");
for (i= 0; i<2; i++) {
resetTime();
k= buscarSeq(b, 26);
if (k!=0) {
mostrar(b, k, 26);
fprintf(stderr, "Bug del profesor: la solucion debio ser %d, no %lld\n",
0, k);
exit(1);
}
tiempo_sec= getTime();
printf("Tiempo secuencial= %d milisegundos\n", tiempo_sec);
}
printf("Calculando en paralelo hasta 5 veces\n");
for (i= 0; i<N_INTENTOS; i++) {
resetTime();
k= buscar(b, 26);
if (k!=0) {
mostrar(b, k, 26);
fprintf(stderr, "La solucion debio ser %d, no %lld\n", 0, k);
exit(1);
}
tiempo_par= getTime();
speedUp= (double)tiempo_sec/tiempo_par;
printf("buscar par tiempo= %d miliseg., speedup= %f\n", tiempo_par, speedUp);
if (speedUp>=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;
}