Commit 5d4e4589 authored by dylan socolobsky's avatar dylan socolobsky
Browse files
parents 5684a940 3b674567
......@@ -20,13 +20,17 @@ resoluciones=$(res_exp1) $(res_exp2)
optimizaciones=O0 O1 O2 O3 Ofast
filtros=asm-Cuadrados asm-Manchas asm-Offset asm-Sharpen #asm-Ruido
filtros+=c-Cuadrados c-Manchas c-Offset c-Sharpen #c-Ruido
filtros+=avx-Cuadrados mvec-Manchas simple-Manchas avx-Offset
# Filtros que se usan para los gráficos simples (tienen implementación asm y c)
filtros_simple=Cuadrados Manchas Offset Sharpen
filtros_avx=Cuadrados Offset
iteraciones?=50
tmancha?=50
retest=
graficos_exp1= # Se rellenan automáticamente
graficos_exp2= # Se rellenan automáticamente
graficos_exp3= # Se rellenan automáticamente
graficos_exp4= # Se rellenan automáticamente
all: graficos
......@@ -122,7 +126,45 @@ $(foreach foto,$(entradas), \
$(foreach filtro,$(filtros_simple), \
$(eval $(call RELACION_template,$(foto),$(filtro)))))
graficos: $(graficos_exp1) $(graficos_exp2)
# AVX_template foto filtro
define AVX_template =
graficos/avx.$(1).$(2).pdf: $(foreach res,$(res_exp1), \
data/$(1).$(res).asm-$(2).O0.stats \
data/$(1).$(res).avx-$(2).O0.stats \
data/$(1).$(res).c-$(2).Ofast.stats)
for res in $(res_exp1); do \
echo $$$$res $$$$(cat data/$(1).$$$$res.asm-$(2).O0.stats) \
$$$$(cat data/$(1).$$$$res.avx-$(2).O0.stats) \
$$$$(cat data/$(1).$$$$res.c-$(2).Ofast.stats); \
done | ./grafico-avx.py $(2) $$@;
graficos_exp3+=graficos/avx.$(1).$(2).pdf
endef
$(foreach foto,$(entradas), \
$(foreach filtro,$(filtros_avx), \
$(eval $(call AVX_template,$(foto),$(filtro)))))
# MANCHAS_template foto filtro
define MANCHAS_template =
graficos/manchas.$(1).pdf: $(foreach res,$(res_exp1), \
data/$(1).$(res).asm-Manchas.O0.stats \
data/$(1).$(res).mvec-Manchas.O0.stats \
data/$(1).$(res).simple-Manchas.O0.stats \
data/$(1).$(res).c-Manchas.Ofast.stats)
for res in $(res_exp1); do \
echo $$$$res $$$$(cat data/$(1).$$$$res.asm-Manchas.O0.stats) \
$$$$(cat data/$(1).$$$$res.mvec-Manchas.O0.stats) \
$$$$(cat data/$(1).$$$$res.simple-Manchas.O0.stats) \
$$$$(cat data/$(1).$$$$res.c-Manchas.Ofast.stats); \
done | ./grafico-manchas.py $$@;
graficos_exp4+=graficos/manchas.$(1).$(2).pdf
endef
$(foreach foto,$(entradas), $(eval $(call MANCHAS_template,$(foto))))
graficos: $(graficos_exp1) $(graficos_exp2) $(graficos_exp3) $(graficos_exp4)
binarios/%/tp2:
$(MAKE) -C binarios $(@:binarios/%=%)
......
#!/usr/bin/env python3
import matplotlib.pyplot as plt
import sys
if len(sys.argv) != 3:
print('Uso: %s filtro salida' % (sys.argv[0],))
exit()
lines = [line.split() for line in sys.stdin.readlines()]
etiquetas = [line[0] for line in lines]
medias_asm = [float(line[1]) for line in lines]
medias_avx = [float(line[3]) for line in lines]
medias_Ofast = [float(line[5]) for line in lines]
errores_asm = [float(line[2]) for line in lines]
errores_avx = [float(line[4]) for line in lines]
errores_Ofast = [float(line[6]) for line in lines]
filtro = sys.argv[1]
salida = sys.argv[2]
plt.xticks(range(0, len(etiquetas), 2), rotation=30, fontsize=8)
plt.yscale('log')
plt.errorbar(etiquetas, medias_asm, yerr=errores_asm, label='ASM')
plt.errorbar(etiquetas, medias_avx, yerr=errores_avx, label='AVX')
plt.errorbar(etiquetas, medias_Ofast, yerr=errores_Ofast, label='C (Ofast)')
plt.xlabel('Tamaños')
plt.ylabel('Ciclos del procesador')
plt.title('Filtro ' + filtro)
plt.legend()
plt.savefig(fname=salida, format='pdf')
#!/usr/bin/env python3
import matplotlib.pyplot as plt
import sys
if len(sys.argv) != 2:
print('Uso: %s salida' % (sys.argv[0],))
exit()
lines = [line.split() for line in sys.stdin.readlines()]
etiquetas = [line[0] for line in lines]
medias_asm = [float(line[1]) for line in lines]
medias_mvec = [float(line[3]) for line in lines]
medias_simple = [float(line[5]) for line in lines]
medias_Ofast = [float(line[7]) for line in lines]
errores_asm = [float(line[2]) for line in lines]
errores_mvec = [float(line[4]) for line in lines]
errores_simple = [float(line[6]) for line in lines]
errores_Ofast = [float(line[8]) for line in lines]
salida = sys.argv[1]
plt.xticks(range(0, len(etiquetas), 2), rotation=30, fontsize=8)
plt.yscale('log')
plt.errorbar(etiquetas, medias_asm, yerr=errores_asm, label='ASM (FPU+Tabla)')
plt.errorbar(etiquetas, medias_simple, yerr=errores_simple, label='ASM (FPU)')
plt.errorbar(etiquetas, medias_mvec, yerr=errores_mvec, label='ASM (libmvec)')
plt.errorbar(etiquetas, medias_Ofast, yerr=errores_Ofast, label='C (Ofast)')
plt.xlabel('Tamaños')
plt.ylabel('Ciclos del procesador')
plt.title('Diferentes implementaciones del filtro Manchas')
plt.legend()
plt.savefig(fname=salida, format='pdf')
......@@ -9,8 +9,9 @@ BIN = tp2
FILTROS = Cuadrados Manchas Offset Ruido Sharpen
FILTROS_OBJ = $(addsuffix .o, $(FILTROS)) $(addsuffix _asm.o, $(FILTROS))\
$(addsuffix _c.o, $(FILTROS)) Manchas_mvec.o Manchas_simple.o
FILTROS_OBJ = $(addsuffix .o, $(FILTROS)) $(addsuffix _asm.o, $(FILTROS)) \
$(addsuffix _c.o, $(FILTROS)) Manchas_mvec.o Manchas_simple.o \
Offset_avx.o Cuadrados_avx.o
LIBS_OBJS = libbmp.o imagenes.o utils.o
MAIN_OBJS = tp2.o cli.o
MAIN_OBJS_CON_PATH = $(addprefix $(BUILD_DIR)/, $(MAIN_OBJS))
......
......@@ -132,7 +132,7 @@ void procesar_opciones(int argc, char **argv, configuracion_t *config) {
} else if (strcmp(tipo_filtro, "asm") == 0) {
config->tipo_filtro = FILTRO_ASM;
} else if (strcmp(tipo_filtro, "simple") == 0 &&
(ES_FILTRO(config, Manchas) || ES_FILTRO(config, Offset))) {
ES_FILTRO(config, Manchas)) {
config->tipo_filtro = FILTRO_SIMPLE;
} else if (strcmp(tipo_filtro, "avx") == 0 &&
(ES_FILTRO(config, Cuadrados) || ES_FILTRO(config, Offset))) {
......
......@@ -10,8 +10,14 @@ void Cuadrados_asm (uint8_t *src, uint8_t *dst, int width, int height,
void Cuadrados_c (uint8_t *src, uint8_t *dst, int width, int height,
int src_row_size, int dst_row_size);
void Cuadrados_avx (uint8_t *src, uint8_t *dst, int width, int height,
int src_row_size, int dst_row_size);
typedef void (Cuadrados_fn_t) (uint8_t*, uint8_t*, int, int, int, int);
static Cuadrados_fn_t* implementaciones[] = {
Cuadrados_c, Cuadrados_asm, Cuadrados_avx
};
void leer_params_Cuadrados(configuracion_t *config, int argc, char *argv[]) {
......@@ -19,7 +25,7 @@ void leer_params_Cuadrados(configuracion_t *config, int argc, char *argv[]) {
void aplicar_Cuadrados(configuracion_t *config)
{
Cuadrados_fn_t *Cuadrados = SWITCH_C_ASM( config, Cuadrados_c, Cuadrados_asm );
Cuadrados_fn_t *Cuadrados = implementaciones[config->tipo_filtro];
buffer_info_t info = config->src;
Cuadrados(info.bytes, config->dst.bytes, info.width, info.height,
info.row_size, config->dst.row_size);
......
section .data
section .rodata
BLACK: times 4 dd 0xFF000000
......
section .rodata
BLACK: times 8 dd 0xFF000000
section .text
global Cuadrados_avx
Cuadrados_avx:
; rdi = uint8_t *src
; rsi = uint8_t *dst
; rdx = int width
; rcx = int height
; r8 = int src_row_size
; r9 = int dst_row_size
; Ajusto por los marcos
sub rdx, 8
shr rdx, 3
; rax = int height
lea rax, [rcx - 8]
vmovdqu ymm7, [BLACK]
; r10 = r8 * 3
lea r10, [r8 + r8*2]
black_start:
lea rcx, [rdx*4 + 4]
.x_loop:
vmovdqu [rsi], ymm7
lea rsi, [rsi + 32]
loop .x_loop
lea rdi, [rdi + r8 * 4]
y_loop:
movdqa [rsi], xmm7
lea rdi, [rdi + 16]
lea rsi, [rsi + 16]
mov rcx, rdx
.x_loop:
vmovdqu ymm0, [rdi]
vpmaxub ymm0, ymm0, [rdi + 4]
vpmaxub ymm0, ymm0, [rdi + 8]
vpmaxub ymm0, ymm0, [rdi + 12]
vpmaxub ymm0, ymm0, [rdi + r8]
vpmaxub ymm0, ymm0, [rdi + r8 + 4]
vpmaxub ymm0, ymm0, [rdi + r8 + 8]
vpmaxub ymm0, ymm0, [rdi + r8 + 12]
vpmaxub ymm0, ymm0, [rdi + r8*2]
vpmaxub ymm0, ymm0, [rdi + r8*2 + 4]
vpmaxub ymm0, ymm0, [rdi + r8*2 + 8]
vpmaxub ymm0, ymm0, [rdi + r8*2 + 12]
vpmaxub ymm0, ymm0, [rdi + r10]
vpmaxub ymm0, ymm0, [rdi + r10 + 4]
vpmaxub ymm0, ymm0, [rdi + r10 + 8]
vpmaxub ymm0, ymm0, [rdi + r10 + 12]
vmovdqu [rsi], ymm0
lea rdi, [rdi + 32]
lea rsi, [rsi + 32]
loop .x_loop
movdqa [rsi], xmm7
lea rdi, [rdi + 16]
lea rsi, [rsi + 16]
dec rax
jnz y_loop
black_end:
lea rcx, [rdx*4 + 4]
.x_loop:
vmovdqu [rsi], ymm7
lea rsi, [rsi + 32]
loop .x_loop
ret
......@@ -19,7 +19,8 @@ BUILD_DIR = ../build
FILTROS = Cuadrados Manchas Offset Ruido Sharpen
FILTROS_OBJ = $(addsuffix .o, $(FILTROS)) $(addsuffix _asm.o, $(FILTROS)) \
$(addsuffix _c.o, $(FILTROS)) Manchas_mvec.o Manchas_simple.o
$(addsuffix _c.o, $(FILTROS)) Manchas_mvec.o Manchas_simple.o \
Offset_avx.o Cuadrados_avx.o
FILTROS_OBJ_CON_PATH = $(addprefix $(BUILD_DIR)/, $(FILTROS_OBJ))
.PHONY: filtros clean
......
section .data
section .rodata
CINCUENTA: dd 50.0
align 16
VEINTICINCO: times 4 dd 25
......
section .data
section .rodata
TAU: dd 6.28318530717958647692528676655900576839433879875021
align 16
VCINCO: times 4 dd 25.0
......
section .data
section .rodata
CTAU: dd 6.283185
CINCUENTA: dd 50.0
VCINCO: dd 25.0
......@@ -278,7 +278,7 @@ Manchas_simple:
jnz .x_loop
; Ya me movi todo un row => decremento los verticales
dec r15
dec r15d
; Si ya llegue abajo del todo salgo, si no repito
jnz .y_loop
......
......@@ -10,6 +10,9 @@ void Offset_asm (uint8_t *src, uint8_t *dst, int width, int height,
void Offset_c (uint8_t *src, uint8_t *dst, int width, int height,
int src_row_size, int dst_row_size);
void Offset_avx (uint8_t *src, uint8_t *dst, int width, int height,
int src_row_size, int dst_row_size);
typedef void (Offset_fn_t) (uint8_t*, uint8_t*, int, int, int, int);
......@@ -17,9 +20,13 @@ void leer_params_Offset(configuracion_t *config, int argc, char *argv[]) {
}
static Offset_fn_t* implementaciones[] = {
Offset_c, Offset_asm, Offset_avx
};
void aplicar_Offset(configuracion_t *config)
{
Offset_fn_t *Offset = SWITCH_C_ASM( config, Offset_c, Offset_asm );
Offset_fn_t *Offset = implementaciones[config->tipo_filtro];
buffer_info_t info = config->src;
Offset(info.bytes, config->dst.bytes, info.width, info.height,
info.row_size, config->dst.row_size);
......
section .data
section .rodata
align 16
BLACK: times 4 dd 0xFF000000
MASK_B: times 4 dd 0x000000FF
......
section .rodata
align 32
BLACK: times 8 dd 0xFF000000
MASK_B: times 8 dd 0x000000FF
MASK_R: times 8 dd 0x00FF0000
section .text
global Offset_avx
Offset_avx:
; rdi = uint8_t *src
; rsi = uint8_t *dst
; rdx = int width
; rcx = int height
; r8 = int src_row_size
; r9 = int dst_row_size
sub rdx, 16
shr rdx, 3
sub rcx, 16
vmovdqa ymm7, [BLACK]
vmovdqa ymm6, [MASK_B]
vmovdqa ymm5, [MASK_R]
; rax = int height
mov rax, rcx
black_start:
lea rcx, [rdx*8 + 16]
.x_loop:
vmovdqu [rsi], ymm7
lea rsi, [rsi + 32]
loop .x_loop
lea rdi, [rdi + r8*8]
y_loop:
vmovdqu [rsi], ymm7
lea rdi, [rdi + 32]
lea rsi, [rsi + 32]
mov rcx, rdx
.x_loop:
vmovdqu ymm1, [rdi + 32]
vpblendvb ymm1, ymm1, [rdi + r8*8], ymm6
vpblendvb ymm1, ymm1, [rdi + r8*8 + 32], ymm5
vmovdqu [rsi], ymm1
lea rdi, [rdi + 32]
lea rsi, [rsi + 32]
loop .x_loop
vmovdqu [rsi], ymm7
lea rdi, [rdi + 32]
lea rsi, [rsi + 32]
dec rax
jnz y_loop
black_end:
lea rcx, [rdx*8 + 16]
.x_loop:
vmovdqu [rsi], ymm7
lea rsi, [rsi + 32]
loop .x_loop
ret
section .data
section .rodata
align 16
%define BLACK 0xFF000000
BLACK_BORDER: dd 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000
......
......@@ -13,6 +13,22 @@ for corrida in corridas:
ok = verificar(corrida['filtro'], corrida['params'], corrida['tolerancia'], 'asm', imagen)
todos_ok = todos_ok and ok
for imagen in archivos:
ok = verificar('Offset', '', 5, 'avx', imagen)
todos_ok = todos_ok and ok
for imagen in archivos:
ok = verificar('Cuadrados', '', 5, 'avx', imagen)
todos_ok = todos_ok and ok
for imagen in archivos:
ok = verificar('Manchas', '100', 5, 'mvec', imagen)
todos_ok = todos_ok and ok
for imagen in archivos:
ok = verificar('Manchas', '100', 5, 'simple', imagen)
todos_ok = todos_ok and ok
if todos_ok:
print(colored("Test de filtros finalizados correctamente", 'green'))
else:
......
......@@ -43,41 +43,56 @@ function run_test {
ret=0; return;
}
for imp in asm; do
# Cuadrados
for s in ${SIZESMEM[*]}; do
run_test "$TP2ALU" "Cuadrados" "$imp" "$TESTINDIR/$img1.$s.bmp" ""
if [ $ret -ne 0 ]; then exit -1; fi
done
# Manchas
for s in ${SIZESMEM[*]}; do
v=0.555
run_test "$TP2ALU" "Manchas" "$imp" "$TESTINDIR/$img1.$s.bmp" "100"
if [ $ret -ne 0 ]; then exit -1; fi
done
# Offset
for s in ${SIZESMEM[*]}; do
run_test "$TP2ALU" "Offset" "$imp" "$TESTINDIR/$img1.$s.bmp" ""
if [ $ret -ne 0 ]; then exit -1; fi
done
# Sharpen
for s in ${SIZESMEM[*]}; do
run_test "$TP2ALU" "Sharpen" "$imp" "$TESTINDIR/$img1.$s.bmp" ""
if [ $ret -ne 0 ]; then exit -1; fi
done
# Ruido
# for s in ${SIZESMEM[*]}; do
# run_test "$TP2ALU" "Ruido" "$imp" "$TESTINDIR/$img1.$s.bmp" ""
# if [ $ret -ne 0 ]; then exit -1; fi
# done
# Cuadrados
for s in ${SIZESMEM[*]}; do
run_test "$TP2ALU" Cuadrados asm "$TESTINDIR/$img1.$s.bmp" ""
if [ $ret -ne 0 ]; then exit -1; fi
done
for s in ${SIZESMEM[*]}; do
run_test "$TP2ALU" Cuadrados avx "$TESTINDIR/$img1.$s.bmp" ""
if [ $ret -ne 0 ]; then exit -1; fi
done
# Manchas
for s in ${SIZESMEM[*]}; do
run_test "$TP2ALU" Manchas asm "$TESTINDIR/$img1.$s.bmp" "100"
if [ $ret -ne 0 ]; then exit -1; fi
done
for s in ${SIZESMEM[*]}; do
run_test "$TP2ALU" Manchas simple "$TESTINDIR/$img1.$s.bmp" "100"
if [ $ret -ne 0 ]; then exit -1; fi
done
for s in ${SIZESMEM[*]}; do
run_test "$TP2ALU" Manchas mvec "$TESTINDIR/$img1.$s.bmp" "100"
if [ $ret -ne 0 ]; then exit -1; fi
done
# Offset
for s in ${SIZESMEM[*]}; do
run_test "$TP2ALU" Offset asm "$TESTINDIR/$img1.$s.bmp" ""
if [ $ret -ne 0 ]; then exit -1; fi
done
for s in ${SIZESMEM[*]}; do
run_test "$TP2ALU" Offset avx "$TESTINDIR/$img1.$s.bmp" ""
if [ $ret -ne 0 ]; then exit -1; fi
done
# Sharpen
for s in ${SIZESMEM[*]}; do
run_test "$TP2ALU" Sharpen asm "$TESTINDIR/$img1.$s.bmp" ""
if [ $ret -ne 0 ]; then exit -1; fi
done
# Ruido
#for s in ${SIZESMEM[*]}; do
# run_test "$TP2ALU" "Ruido" "$imp" "$TESTINDIR/$img1.$s.bmp" ""
# if [ $ret -ne 0 ]; then exit -1; fi
#done
echo ""
echo -e "$VERDE Felicitaciones los test de MEMORIA finalizaron correctamente $DEFAULT"
......@@ -10,7 +10,6 @@
#define FILTRO_AVX 2
/* Manchas */
#define FILTRO_MVEC 2
/* Manchas, Offset */
#define FILTRO_SIMPLE 3
#define ES_FILTRO(config, nombre) (strcmp(config->nombre_filtro, #nombre) == 0)
......@@ -73,7 +72,16 @@ typedef struct configuracion_t {
} configuracion_t;
#define SWITCH_C_ASM(config,c_ver,asm_ver) ( config->tipo_filtro == FILTRO_C ? c_ver : asm_ver )
#define C_ASM(config) ( SWITCH_C_ASM(config, "C", "ASM") )
#define C_ASM(config) (config->tipo_filtro == FILTRO_C ? "C" \
: config->tipo_filtro == FILTRO_ASM ? "ASM" \
: config->tipo_filtro == FILTRO_MVEC \
&& ES_FILTRO(config, Manchas) ? "MVEC" \
: config->tipo_filtro == FILTRO_SIMPLE \
&& ES_FILTRO(config, Manchas) ? "SIMPLE" \
: config->tipo_filtro == FILTRO_AVX \
&& (ES_FILTRO(config, Cuadrados) \
|| ES_FILTRO(config, Offset)) ? "AVX" \
: "Desconocido")
typedef void (lector_params_fn_t) (configuracion_t *config, int, char *[]);
typedef void (aplicador_fn_t) (configuracion_t*);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment