diff --git a/.gitignore b/.gitignore index c2769f1..732b31c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ myexp +test_auto_vectorize +**/*.s **/*.o **/*.swp diff --git a/HW1_111550013.zip b/HW1_111550013.zip new file mode 100644 index 0000000..00ccbb3 Binary files /dev/null and b/HW1_111550013.zip differ diff --git a/part1/vectorOP.cpp b/part1/vectorOP.cpp index e4e5e63..8b47e3f 100644 --- a/part1/vectorOP.cpp +++ b/part1/vectorOP.cpp @@ -1,4 +1,6 @@ #include "PPintrin.h" +#include +#include // implementation of absSerial(), but it is vectorized using PP intrinsics void absVector(float *values, float *output, int N) @@ -84,6 +86,9 @@ void clampedExpVector(float *values, int *exponents, float *output, int N) _pp_vload_int(y, exponents + i, maskAll); // y = exponents[i]; } + cout << "min exponents: " << *min_element(y.value, y.value+VECTOR_WIDTH) << endl; + cout << "max exponents: " << *max_element(y.value, y.value+VECTOR_WIDTH) << endl; + _pp_vset_float(result, 1.f, maskAll); maskNonZero = _pp_init_ones(); while (_pp_cntbits(maskNonZero) > 0) { diff --git a/part2/test.sh b/part2/test.sh new file mode 100644 index 0000000..46ab149 --- /dev/null +++ b/part2/test.sh @@ -0,0 +1,9 @@ +RUNS=${1:-5} +median() { sort -n | awk '{a[NR]=$1} END{print (NR%2)?a[(NR+1)/2]:(a[NR/2]+a[NR/2+1])/2}'; } +for cfg in "novec:" "vec:VECTORIZE=1" "avx2:VECTORIZE=1 AVX2=1"; do + name=${cfg%%:*}; flags=${cfg#*:} + make -s clean; make -s $flags >/dev/null 2>&1 || { echo "build $name failed"; exit 1; } + t=$(for r in $(seq $RUNS); do ./test_auto_vectorize -t 1 | grep -oE '^[0-9.]+'; done | median) + echo "$name $t"; eval "T_$name=$t" +done +awk -v n=$T_novec -v v=$T_vec -v a=$T_avx2 'BEGIN{printf "vec/novec speedup: %.2fx\navx2/vec speedup: %.2fx\navx2/novec speedup: %.2fx\n", n/v, v/a, n/a}' diff --git a/part2/test1.c b/part2/test1.c index 686f5f7..479719b 100644 --- a/part2/test1.c +++ b/part2/test1.c @@ -1,7 +1,10 @@ #include "test.h" -void test1(float *a, float *b, float *c, int N) { +void test1(float *__restrict a, float *__restrict b, float *__restrict c, int N) { __builtin_assume(N == 1024); + a = (float *)__builtin_assume_aligned(a, 32); + b = (float *)__builtin_assume_aligned(b, 32); + c = (float *)__builtin_assume_aligned(c, 32); for (int i=0; i a[j]) - c[j] = b[j]; + if (b[j] > a[j]) c[j] = b[j]; + else c[j] = a[j]; } } } diff --git a/part2/test2.c.orig b/part2/test2.c.orig new file mode 100644 index 0000000..eac500e --- /dev/null +++ b/part2/test2.c.orig @@ -0,0 +1,19 @@ +#include "test.h" + +void test2(float *__restrict a, float *__restrict b, float *__restrict c, int N) +{ + __builtin_assume(N == 1024); + a = (float *)__builtin_assume_aligned(a, 16); + b = (float *)__builtin_assume_aligned(b, 16); + + for (int i = 0; i < I; i++) + { + for (int j = 0; j < N; j++) + { + /* max() */ + c[j] = a[j]; + if (b[j] > a[j]) + c[j] = b[j]; + } + } +}