From bf65e372029deb236eca4fab0d8d46cace0a3ed6 Mon Sep 17 00:00:00 2001 From: Yi-Ting Shih Date: Mon, 5 Oct 2026 04:41:24 +0800 Subject: [PATCH] init: HW1 --- part1/Makefile | 20 +++ part1/PPintrin.cpp | 304 ++++++++++++++++++++++++++++++++++++++++++++ part1/PPintrin.h | 123 ++++++++++++++++++ part1/PPintrin.o | Bin 0 -> 29896 bytes part1/def.h | 5 + part1/logger.cpp | 66 ++++++++++ part1/logger.h | 37 ++++++ part1/logger.o | Bin 0 -> 5608 bytes part1/main.cpp | 204 +++++++++++++++++++++++++++++ part1/myexp | Bin 0 -> 38472 bytes part1/serialOP.cpp | 61 +++++++++ part1/vectorOP.cpp | 72 +++++++++++ part2/Makefile | 53 ++++++++ part2/fasttime.h | 97 ++++++++++++++ part2/main.c | 91 +++++++++++++ part2/test.h | 7 + part2/test1.c | 11 ++ part2/test2.c | 19 +++ part2/test2.c.patch | 13 ++ part2/test3.c | 14 ++ 20 files changed, 1197 insertions(+) create mode 100644 part1/Makefile create mode 100644 part1/PPintrin.cpp create mode 100644 part1/PPintrin.h create mode 100644 part1/PPintrin.o create mode 100644 part1/def.h create mode 100644 part1/logger.cpp create mode 100644 part1/logger.h create mode 100644 part1/logger.o create mode 100644 part1/main.cpp create mode 100755 part1/myexp create mode 100644 part1/serialOP.cpp create mode 100644 part1/vectorOP.cpp create mode 100644 part2/Makefile create mode 100644 part2/fasttime.h create mode 100644 part2/main.c create mode 100644 part2/test.h create mode 100644 part2/test1.c create mode 100644 part2/test2.c create mode 100644 part2/test2.c.patch create mode 100644 part2/test3.c diff --git a/part1/Makefile b/part1/Makefile new file mode 100644 index 0000000..46298fa --- /dev/null +++ b/part1/Makefile @@ -0,0 +1,20 @@ +CXX := g++ +CXXFLAGS := -O3 -std=c++17 -Wall + +ifneq ($(VECTOR_WIDTH),) + CXXFLAGS += -DVECTOR_WIDTH=$(VECTOR_WIDTH) +endif + +all: myexp + +logger.o: logger.cpp logger.h PPintrin.h PPintrin.cpp def.h + $(CXX) $(CXXFLAGS) -c logger.cpp + +PPintrin.o: PPintrin.cpp PPintrin.h logger.cpp logger.h def.h + $(CXX) $(CXXFLAGS) -c PPintrin.cpp + +myexp: PPintrin.o logger.o main.cpp serialOP.cpp vectorOP.cpp + $(CXX) $(CXXFLAGS) logger.o PPintrin.o main.cpp serialOP.cpp vectorOP.cpp -o myexp + +clean: + $(RM) *.o *.s myexp *~ diff --git a/part1/PPintrin.cpp b/part1/PPintrin.cpp new file mode 100644 index 0000000..311a8ee --- /dev/null +++ b/part1/PPintrin.cpp @@ -0,0 +1,304 @@ +#include "PPintrin.h" +#include "logger.h" + +//****************** +//* Implementation * +//****************** + +__pp_mask _pp_init_ones(int first) +{ + __pp_mask mask; + for (int i = 0; i < VECTOR_WIDTH; i++) + { + mask.value[i] = (i < first) ? true : false; + } + return mask; +} + +__pp_mask _pp_mask_not(__pp_mask &maska) +{ + __pp_mask resultMask; + for (int i = 0; i < VECTOR_WIDTH; i++) + { + resultMask.value[i] = !maska.value[i]; + } + PPLogger.addLog("masknot", _pp_init_ones(), VECTOR_WIDTH); + return resultMask; +} + +__pp_mask _pp_mask_or(__pp_mask &maska, __pp_mask &maskb) +{ + __pp_mask resultMask; + for (int i = 0; i < VECTOR_WIDTH; i++) + { + resultMask.value[i] = maska.value[i] | maskb.value[i]; + } + PPLogger.addLog("maskor", _pp_init_ones(), VECTOR_WIDTH); + return resultMask; +} + +__pp_mask _pp_mask_and(__pp_mask &maska, __pp_mask &maskb) +{ + __pp_mask resultMask; + for (int i = 0; i < VECTOR_WIDTH; i++) + { + resultMask.value[i] = maska.value[i] && maskb.value[i]; + } + PPLogger.addLog("maskand", _pp_init_ones(), VECTOR_WIDTH); + return resultMask; +} + +int _pp_cntbits(__pp_mask &maska) +{ + int count = 0; + for (int i = 0; i < VECTOR_WIDTH; i++) + { + if (maska.value[i]) + count++; + } + PPLogger.addLog("cntbits", _pp_init_ones(), VECTOR_WIDTH); + return count; +} + +template +void _pp_vset(__pp_vec &vecResult, T value, __pp_mask &mask) +{ + for (int i = 0; i < VECTOR_WIDTH; i++) + { + vecResult.value[i] = mask.value[i] ? value : vecResult.value[i]; + } + PPLogger.addLog("vset", mask, VECTOR_WIDTH); +} + +template void _pp_vset(__pp_vec_float &vecResult, float value, __pp_mask &mask); +template void _pp_vset(__pp_vec_int &vecResult, int value, __pp_mask &mask); + +void _pp_vset_float(__pp_vec_float &vecResult, float value, __pp_mask &mask) { _pp_vset(vecResult, value, mask); } +void _pp_vset_int(__pp_vec_int &vecResult, int value, __pp_mask &mask) { _pp_vset(vecResult, value, mask); } + +__pp_vec_float _pp_vset_float(float value) +{ + __pp_vec_float vecResult; + __pp_mask mask = _pp_init_ones(); + _pp_vset_float(vecResult, value, mask); + return vecResult; +} +__pp_vec_int _pp_vset_int(int value) +{ + __pp_vec_int vecResult; + __pp_mask mask = _pp_init_ones(); + _pp_vset_int(vecResult, value, mask); + return vecResult; +} + +template +void _pp_vmove(__pp_vec &dest, __pp_vec &src, __pp_mask &mask) +{ + for (int i = 0; i < VECTOR_WIDTH; i++) + { + dest.value[i] = mask.value[i] ? src.value[i] : dest.value[i]; + } + PPLogger.addLog("vmove", mask, VECTOR_WIDTH); +} + +template void _pp_vmove(__pp_vec_float &dest, __pp_vec_float &src, __pp_mask &mask); +template void _pp_vmove(__pp_vec_int &dest, __pp_vec_int &src, __pp_mask &mask); + +void _pp_vmove_float(__pp_vec_float &dest, __pp_vec_float &src, __pp_mask &mask) { _pp_vmove(dest, src, mask); } +void _pp_vmove_int(__pp_vec_int &dest, __pp_vec_int &src, __pp_mask &mask) { _pp_vmove(dest, src, mask); } + +template +void _pp_vload(__pp_vec &dest, T *src, __pp_mask &mask) +{ + for (int i = 0; i < VECTOR_WIDTH; i++) + { + dest.value[i] = mask.value[i] ? src[i] : dest.value[i]; + } + PPLogger.addLog("vload", mask, VECTOR_WIDTH); +} + +template void _pp_vload(__pp_vec_float &dest, float *src, __pp_mask &mask); +template void _pp_vload(__pp_vec_int &dest, int *src, __pp_mask &mask); + +void _pp_vload_float(__pp_vec_float &dest, float *src, __pp_mask &mask) { _pp_vload(dest, src, mask); } +void _pp_vload_int(__pp_vec_int &dest, int *src, __pp_mask &mask) { _pp_vload(dest, src, mask); } + +template +void _pp_vstore(T *dest, __pp_vec &src, __pp_mask &mask) +{ + for (int i = 0; i < VECTOR_WIDTH; i++) + { + dest[i] = mask.value[i] ? src.value[i] : dest[i]; + } + PPLogger.addLog("vstore", mask, VECTOR_WIDTH); +} + +template void _pp_vstore(float *dest, __pp_vec_float &src, __pp_mask &mask); +template void _pp_vstore(int *dest, __pp_vec_int &src, __pp_mask &mask); + +void _pp_vstore_float(float *dest, __pp_vec_float &src, __pp_mask &mask) { _pp_vstore(dest, src, mask); } +void _pp_vstore_int(int *dest, __pp_vec_int &src, __pp_mask &mask) { _pp_vstore(dest, src, mask); } + +template +void _pp_vadd(__pp_vec &vecResult, __pp_vec &veca, __pp_vec &vecb, __pp_mask &mask) +{ + for (int i = 0; i < VECTOR_WIDTH; i++) + { + vecResult.value[i] = mask.value[i] ? (veca.value[i] + vecb.value[i]) : vecResult.value[i]; + } + PPLogger.addLog("vadd", mask, VECTOR_WIDTH); +} + +template void _pp_vadd(__pp_vec_float &vecResult, __pp_vec_float &veca, __pp_vec_float &vecb, __pp_mask &mask); +template void _pp_vadd(__pp_vec_int &vecResult, __pp_vec_int &veca, __pp_vec_int &vecb, __pp_mask &mask); + +void _pp_vadd_float(__pp_vec_float &vecResult, __pp_vec_float &veca, __pp_vec_float &vecb, __pp_mask &mask) { _pp_vadd(vecResult, veca, vecb, mask); } +void _pp_vadd_int(__pp_vec_int &vecResult, __pp_vec_int &veca, __pp_vec_int &vecb, __pp_mask &mask) { _pp_vadd(vecResult, veca, vecb, mask); } + +template +void _pp_vsub(__pp_vec &vecResult, __pp_vec &veca, __pp_vec &vecb, __pp_mask &mask) +{ + for (int i = 0; i < VECTOR_WIDTH; i++) + { + vecResult.value[i] = mask.value[i] ? (veca.value[i] - vecb.value[i]) : vecResult.value[i]; + } + PPLogger.addLog("vsub", mask, VECTOR_WIDTH); +} + +template void _pp_vsub(__pp_vec_float &vecResult, __pp_vec_float &veca, __pp_vec_float &vecb, __pp_mask &mask); +template void _pp_vsub(__pp_vec_int &vecResult, __pp_vec_int &veca, __pp_vec_int &vecb, __pp_mask &mask); + +void _pp_vsub_float(__pp_vec_float &vecResult, __pp_vec_float &veca, __pp_vec_float &vecb, __pp_mask &mask) { _pp_vsub(vecResult, veca, vecb, mask); } +void _pp_vsub_int(__pp_vec_int &vecResult, __pp_vec_int &veca, __pp_vec_int &vecb, __pp_mask &mask) { _pp_vsub(vecResult, veca, vecb, mask); } + +template +void _pp_vmult(__pp_vec &vecResult, __pp_vec &veca, __pp_vec &vecb, __pp_mask &mask) +{ + for (int i = 0; i < VECTOR_WIDTH; i++) + { + vecResult.value[i] = mask.value[i] ? (veca.value[i] * vecb.value[i]) : vecResult.value[i]; + } + PPLogger.addLog("vmult", mask, VECTOR_WIDTH); +} + +template void _pp_vmult(__pp_vec_float &vecResult, __pp_vec_float &veca, __pp_vec_float &vecb, __pp_mask &mask); +template void _pp_vmult(__pp_vec_int &vecResult, __pp_vec_int &veca, __pp_vec_int &vecb, __pp_mask &mask); + +void _pp_vmult_float(__pp_vec_float &vecResult, __pp_vec_float &veca, __pp_vec_float &vecb, __pp_mask &mask) { _pp_vmult(vecResult, veca, vecb, mask); } +void _pp_vmult_int(__pp_vec_int &vecResult, __pp_vec_int &veca, __pp_vec_int &vecb, __pp_mask &mask) { _pp_vmult(vecResult, veca, vecb, mask); } + +template +void _pp_vdiv(__pp_vec &vecResult, __pp_vec &veca, __pp_vec &vecb, __pp_mask &mask) +{ + for (int i = 0; i < VECTOR_WIDTH; i++) + { + vecResult.value[i] = mask.value[i] ? (veca.value[i] / vecb.value[i]) : vecResult.value[i]; + } + PPLogger.addLog("vdiv", mask, VECTOR_WIDTH); +} + +template void _pp_vdiv(__pp_vec_float &vecResult, __pp_vec_float &veca, __pp_vec_float &vecb, __pp_mask &mask); +template void _pp_vdiv(__pp_vec_int &vecResult, __pp_vec_int &veca, __pp_vec_int &vecb, __pp_mask &mask); + +void _pp_vdiv_float(__pp_vec_float &vecResult, __pp_vec_float &veca, __pp_vec_float &vecb, __pp_mask &mask) { _pp_vdiv(vecResult, veca, vecb, mask); } +void _pp_vdiv_int(__pp_vec_int &vecResult, __pp_vec_int &veca, __pp_vec_int &vecb, __pp_mask &mask) { _pp_vdiv(vecResult, veca, vecb, mask); } + +template +void _pp_vabs(__pp_vec &vecResult, __pp_vec &veca, __pp_mask &mask) +{ + for (int i = 0; i < VECTOR_WIDTH; i++) + { + vecResult.value[i] = mask.value[i] ? (abs(veca.value[i])) : vecResult.value[i]; + } + PPLogger.addLog("vabs", mask, VECTOR_WIDTH); +} + +template void _pp_vabs(__pp_vec_float &vecResult, __pp_vec_float &veca, __pp_mask &mask); +template void _pp_vabs(__pp_vec_int &vecResult, __pp_vec_int &veca, __pp_mask &mask); + +void _pp_vabs_float(__pp_vec_float &vecResult, __pp_vec_float &veca, __pp_mask &mask) { _pp_vabs(vecResult, veca, mask); } +void _pp_vabs_int(__pp_vec_int &vecResult, __pp_vec_int &veca, __pp_mask &mask) { _pp_vabs(vecResult, veca, mask); } + +template +void _pp_vgt(__pp_mask &maskResult, __pp_vec &veca, __pp_vec &vecb, __pp_mask &mask) +{ + for (int i = 0; i < VECTOR_WIDTH; i++) + { + maskResult.value[i] = mask.value[i] ? (veca.value[i] > vecb.value[i]) : maskResult.value[i]; + } + PPLogger.addLog("vgt", mask, VECTOR_WIDTH); +} + +template void _pp_vgt(__pp_mask &maskResult, __pp_vec_float &veca, __pp_vec_float &vecb, __pp_mask &mask); +template void _pp_vgt(__pp_mask &maskResult, __pp_vec_int &veca, __pp_vec_int &vecb, __pp_mask &mask); + +void _pp_vgt_float(__pp_mask &maskResult, __pp_vec_float &veca, __pp_vec_float &vecb, __pp_mask &mask) { _pp_vgt(maskResult, veca, vecb, mask); } +void _pp_vgt_int(__pp_mask &maskResult, __pp_vec_int &veca, __pp_vec_int &vecb, __pp_mask &mask) { _pp_vgt(maskResult, veca, vecb, mask); } + +template +void _pp_vlt(__pp_mask &maskResult, __pp_vec &veca, __pp_vec &vecb, __pp_mask &mask) +{ + for (int i = 0; i < VECTOR_WIDTH; i++) + { + maskResult.value[i] = mask.value[i] ? (veca.value[i] < vecb.value[i]) : maskResult.value[i]; + } + PPLogger.addLog("vlt", mask, VECTOR_WIDTH); +} + +template void _pp_vlt(__pp_mask &maskResult, __pp_vec_float &veca, __pp_vec_float &vecb, __pp_mask &mask); +template void _pp_vlt(__pp_mask &maskResult, __pp_vec_int &veca, __pp_vec_int &vecb, __pp_mask &mask); + +void _pp_vlt_float(__pp_mask &maskResult, __pp_vec_float &veca, __pp_vec_float &vecb, __pp_mask &mask) { _pp_vlt(maskResult, veca, vecb, mask); } +void _pp_vlt_int(__pp_mask &maskResult, __pp_vec_int &veca, __pp_vec_int &vecb, __pp_mask &mask) { _pp_vlt(maskResult, veca, vecb, mask); } + +template +void _pp_veq(__pp_mask &maskResult, __pp_vec &veca, __pp_vec &vecb, __pp_mask &mask) +{ + for (int i = 0; i < VECTOR_WIDTH; i++) + { + maskResult.value[i] = mask.value[i] ? (veca.value[i] == vecb.value[i]) : maskResult.value[i]; + } + PPLogger.addLog("veq", mask, VECTOR_WIDTH); +} + +template void _pp_veq(__pp_mask &maskResult, __pp_vec_float &veca, __pp_vec_float &vecb, __pp_mask &mask); +template void _pp_veq(__pp_mask &maskResult, __pp_vec_int &veca, __pp_vec_int &vecb, __pp_mask &mask); + +void _pp_veq_float(__pp_mask &maskResult, __pp_vec_float &veca, __pp_vec_float &vecb, __pp_mask &mask) { _pp_veq(maskResult, veca, vecb, mask); } +void _pp_veq_int(__pp_mask &maskResult, __pp_vec_int &veca, __pp_vec_int &vecb, __pp_mask &mask) { _pp_veq(maskResult, veca, vecb, mask); } + +template +void _pp_hadd(__pp_vec &vecResult, __pp_vec &vec) +{ + for (int i = 0; i < VECTOR_WIDTH / 2; i++) + { + T result = vec.value[2 * i] + vec.value[2 * i + 1]; + vecResult.value[2 * i] = result; + vecResult.value[2 * i + 1] = result; + } + PPLogger.addLog("hadd", _pp_init_ones(), VECTOR_WIDTH); +} + +template void _pp_hadd(__pp_vec_float &vecResult, __pp_vec_float &vec); + +void _pp_hadd_float(__pp_vec_float &vecResult, __pp_vec_float &vec) { _pp_hadd(vecResult, vec); } + +template +void _pp_interleave(__pp_vec &vecResult, __pp_vec vec) +{ + for (int i = 0; i < VECTOR_WIDTH; i++) + { + int index = i < VECTOR_WIDTH / 2 ? (2 * i) : (2 * (i - VECTOR_WIDTH / 2) + 1); + vecResult.value[i] = vec.value[index]; + } + PPLogger.addLog("interleave", _pp_init_ones(), VECTOR_WIDTH); +} + +template void _pp_interleave(__pp_vec_float &vecResult, __pp_vec_float vec); + +void _pp_interleave_float(__pp_vec_float &vecResult, __pp_vec_float vec) { _pp_interleave(vecResult, vec); } + +void addUserLog(const char *logStr) +{ + PPLogger.addLog(logStr, _pp_init_ones(), 0); +} diff --git a/part1/PPintrin.h b/part1/PPintrin.h new file mode 100644 index 0000000..f029a87 --- /dev/null +++ b/part1/PPintrin.h @@ -0,0 +1,123 @@ +#ifndef PPINTRIN_H_ +#define PPINTRIN_H_ + +#include +#include +#include "logger.h" +#include "def.h" +//******************* +//* Type Definition * +//******************* + +extern Logger PPLogger; + +template +struct __pp_vec { + T value[VECTOR_WIDTH]; +}; + +// Declare a mask with __pp_mask +struct __pp_mask : __pp_vec {}; + +// Declare a floating point vector register with __pp_vec_float +#define __pp_vec_float __pp_vec + +// Declare an integer vector register with __pp_vec_int +#define __pp_vec_int __pp_vec + +//*********************** +//* Function Definition * +//*********************** + +// Return a mask initialized to 1 in the first N lanes and 0 in the others +__pp_mask _pp_init_ones(int first = VECTOR_WIDTH); + +// Return the inverse of maska +__pp_mask _pp_mask_not(__pp_mask &maska); + +// Return (maska | maskb) +__pp_mask _pp_mask_or(__pp_mask &maska, __pp_mask &maskb); + +// Return (maska & maskb) +__pp_mask _pp_mask_and(__pp_mask &maska, __pp_mask &maskb); + +// Count the number of 1s in maska +int _pp_cntbits(__pp_mask &maska); + +// Set register to value if vector lane is active +// otherwise keep the old value +void _pp_vset_float(__pp_vec_float &vecResult, float value, __pp_mask &mask); +void _pp_vset_int(__pp_vec_int &vecResult, int value, __pp_mask &mask); +// For user's convenience, returns a vector register with all lanes initialized to value +__pp_vec_float _pp_vset_float(float value); +__pp_vec_int _pp_vset_int(int value); + +// Copy values from vector register src to vector register dest if vector lane active +// otherwise keep the old value +void _pp_vmove_float(__pp_vec_float &dest, __pp_vec_float &src, __pp_mask &mask); +void _pp_vmove_int(__pp_vec_int &dest, __pp_vec_int &src, __pp_mask &mask); + +// Load values from array src to vector register dest if vector lane active +// otherwise keep the old value +void _pp_vload_float(__pp_vec_float &dest, float* src, __pp_mask &mask); +void _pp_vload_int(__pp_vec_int &dest, int* src, __pp_mask &mask); + +// Store values from vector register src to array dest if vector lane active +// otherwise keep the old value +void _pp_vstore_float(float* dest, __pp_vec_float &src, __pp_mask &mask); +void _pp_vstore_int(int* dest, __pp_vec_int &src, __pp_mask &mask); + +// Return calculation of (veca + vecb) if vector lane active +// otherwise keep the old value +void _pp_vadd_float(__pp_vec_float &vecResult, __pp_vec_float &veca, __pp_vec_float &vecb, __pp_mask &mask); +void _pp_vadd_int(__pp_vec_int &vecResult, __pp_vec_int &veca, __pp_vec_int &vecb, __pp_mask &mask); + +// Return calculation of (veca - vecb) if vector lane active +// otherwise keep the old value +void _pp_vsub_float(__pp_vec_float &vecResult, __pp_vec_float &veca, __pp_vec_float &vecb, __pp_mask &mask); +void _pp_vsub_int(__pp_vec_int &vecResult, __pp_vec_int &veca, __pp_vec_int &vecb, __pp_mask &mask); + +// Return calculation of (veca * vecb) if vector lane active +// otherwise keep the old value +void _pp_vmult_float(__pp_vec_float &vecResult, __pp_vec_float &veca, __pp_vec_float &vecb, __pp_mask &mask); +void _pp_vmult_int(__pp_vec_int &vecResult, __pp_vec_int &veca, __pp_vec_int &vecb, __pp_mask &mask); + +// Return calculation of (veca / vecb) if vector lane active +// otherwise keep the old value +void _pp_vdiv_float(__pp_vec_float &vecResult, __pp_vec_float &veca, __pp_vec_float &vecb, __pp_mask &mask); +void _pp_vdiv_int(__pp_vec_int &vecResult, __pp_vec_int &veca, __pp_vec_int &vecb, __pp_mask &mask); + + +// Return calculation of absolute value abs(veca) if vector lane active +// otherwise keep the old value +void _pp_vabs_float(__pp_vec_float &vecResult, __pp_vec_float &veca, __pp_mask &mask); +void _pp_vabs_int(__pp_vec_int &vecResult, __pp_vec_int &veca, __pp_mask &mask); + +// Return a mask of (veca > vecb) if vector lane active +// otherwise keep the old value +void _pp_vgt_float(__pp_mask &vecResult, __pp_vec_float &veca, __pp_vec_float &vecb, __pp_mask &mask); +void _pp_vgt_int(__pp_mask &vecResult, __pp_vec_int &veca, __pp_vec_int &vecb, __pp_mask &mask); + +// Return a mask of (veca < vecb) if vector lane active +// otherwise keep the old value +void _pp_vlt_float(__pp_mask &vecResult, __pp_vec_float &veca, __pp_vec_float &vecb, __pp_mask &mask); +void _pp_vlt_int(__pp_mask &vecResult, __pp_vec_int &veca, __pp_vec_int &vecb, __pp_mask &mask); + +// Return a mask of (veca == vecb) if vector lane active +// otherwise keep the old value +void _pp_veq_float(__pp_mask &vecResult, __pp_vec_float &veca, __pp_vec_float &vecb, __pp_mask &mask); +void _pp_veq_int(__pp_mask &vecResult, __pp_vec_int &veca, __pp_vec_int &vecb, __pp_mask &mask); + +// Adds up adjacent pairs of elements, so +// [0 1 2 3] -> [0+1 0+1 2+3 2+3] +void _pp_hadd_float(__pp_vec_float &vecResult, __pp_vec_float &vec); + +// Performs an even-odd interleaving where all even-indexed elements move to front half +// of the array and odd-indexed to the back half, so +// [0 1 2 3 4 5 6 7] -> [0 2 4 6 1 3 5 7] +void _pp_interleave_float(__pp_vec_float &vecResult, __pp_vec_float vec); + +// Add a customized log to help debugging +void addUserLog(const char * logStr); + +#endif diff --git a/part1/PPintrin.o b/part1/PPintrin.o new file mode 100644 index 0000000000000000000000000000000000000000..33c3ac7076dfa85c95640ac7ab220902b92a83b7 GIT binary patch literal 29896 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 P1_s#p8%Qq*qw5C%Mt(C+ literal 0 HcmV?d00001 diff --git a/part1/def.h b/part1/def.h new file mode 100644 index 0000000..a617554 --- /dev/null +++ b/part1/def.h @@ -0,0 +1,5 @@ +// Define vector unit width here +#ifndef VECTOR_WIDTH +#define VECTOR_WIDTH 4 +#endif +#define EXP_MAX 10 diff --git a/part1/logger.cpp b/part1/logger.cpp new file mode 100644 index 0000000..c74d795 --- /dev/null +++ b/part1/logger.cpp @@ -0,0 +1,66 @@ +#include "logger.h" +#include "PPintrin.h" + +void Logger::addLog(const char *instruction, __pp_mask mask, int N) +{ + Log newLog; + strcpy(newLog.instruction, instruction); + newLog.mask = 0; + for (int i = 0; i < N; i++) + { + if (mask.value[i]) + { + newLog.mask |= (((unsigned long long)1) << i); + stats.utilized_lane++; + } + } + stats.total_lane += N; + stats.total_instructions += (N > 0); + log.push_back(newLog); +} + +void Logger::printStats() +{ + printf("****************** Printing Vector Unit Statistics *******************\n"); + printf("Vector Width: %d\n", VECTOR_WIDTH); + printf("Total Vector Instructions: %lld\n", stats.total_instructions); + printf("Vector Utilization: %.1f%%\n", (double)stats.utilized_lane / stats.total_lane * 100); + printf("Utilized Vector Lanes: %lld\n", stats.utilized_lane); + printf("Total Vector Lanes: %lld\n", stats.total_lane); +} + +void Logger::printLog() +{ + printf("***************** Printing Vector Unit Execution Log *****************\n"); + printf(" Instruction | Vector Lane Occupancy ('*' for active, '_' for inactive)\n"); + printf("------------- --------------------------------------------------------\n"); + for (int i = 0; i < log.size(); i++) + { + printf("%12s | ", log[i].instruction); + for (int j = 0; j < VECTOR_WIDTH; j++) + { + if (log[i].mask & (((unsigned long long)1) << j)) + { + printf("*"); + } + else + { + printf("_"); + } + } + printf("\n"); + } +} + +void Logger::refresh() +{ + stats.total_instructions = 0; + stats.total_lane = 0; + stats.utilized_lane = 0; + fflush(stdout); +}; + +unsigned long long Logger::getTotalInstrs() +{ + return stats.total_instructions; +} diff --git a/part1/logger.h b/part1/logger.h new file mode 100644 index 0000000..2dc2634 --- /dev/null +++ b/part1/logger.h @@ -0,0 +1,37 @@ +#ifndef LOGGER_H_ +#define LOGGER_H_ + +#include +#include +#include +using namespace std; + +#define MAX_INST_LEN 32 + +struct __pp_mask; + +struct Log { + char instruction[MAX_INST_LEN]; + unsigned long long mask; // support vector width up to 64 +}; + +struct Statistics { + unsigned long long utilized_lane; + unsigned long long total_lane; + unsigned long long total_instructions; +}; + +class Logger { + private: + vector log; + Statistics stats; + + public: + void addLog(const char * instruction, __pp_mask mask, int N = 0); + void printStats(); + void printLog(); + void refresh(); + unsigned long long getTotalInstrs(); +}; + +#endif diff --git a/part1/logger.o b/part1/logger.o new file mode 100644 index 0000000000000000000000000000000000000000..62a42b9dbea10010c3d0f774cbcf811e15ec3732 GIT binary patch literal 5608 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 literal 0 HcmV?d00001 diff --git a/part1/main.cpp b/part1/main.cpp new file mode 100644 index 0000000..e1c5ac3 --- /dev/null +++ b/part1/main.cpp @@ -0,0 +1,204 @@ +#include +#include +#include +#include +#include "logger.h" +#include +#include "def.h" +using namespace std; + +Logger PPLogger; + +void usage(const char *progname); +void initValue(float *values, int *exponents, float *output, float *gold, unsigned int N); +void absSerial(float *values, float *output, int N); +void absVector(float *values, float *output, int N); +void clampedExpSerial(float *values, int *exponents, float *output, int N); +void clampedExpVector(float *values, int *exponents, float *output, int N); +float arraySumSerial(float *values, int N); +float arraySumVector(float *values, int N); +bool verifyResult(float *values, int *exponents, float *output, float *gold, int N); + +int main(int argc, char *argv[]) +{ + int N = 16; + bool printLog = false; + + // parse commandline options //////////////////////////////////////////// + int opt; + static struct option long_options[] = { + {"size", 1, 0, 's'}, + {"log", 0, 0, 'l'}, + {"help", 0, 0, '?'}, + {0, 0, 0, 0}}; + + while ((opt = getopt_long(argc, argv, "s:l?", long_options, NULL)) != EOF) + { + + switch (opt) + { + case 's': + N = atoi(optarg); + if (N <= 0) + { + printf("Error: Workload size is set to %d (<0).\n", N); + return -1; + } + break; + case 'l': + printLog = true; + break; + case '?': + default: + usage(argv[0]); + return 1; + } + } + + float *values = new float[N + VECTOR_WIDTH]; + int *exponents = new int[N + VECTOR_WIDTH]; + float *output = new float[N + VECTOR_WIDTH]; + float *gold = new float[N + VECTOR_WIDTH]; + initValue(values, exponents, output, gold, N); + + clampedExpSerial(values, exponents, gold, N); + clampedExpVector(values, exponents, output, N); + + //absSerial(values, gold, N); + //absVector(values, output, N); + + printf("\e[1;31mCLAMPED EXPONENT\e[0m (required) \n"); + bool clampedCorrect = verifyResult(values, exponents, output, gold, N); + if (printLog) + PPLogger.printLog(); + PPLogger.printStats(); + + printf("************************ Result Verification *************************\n"); + if (!clampedCorrect) + { + printf("@@@ ClampedExp Failed!!!\n"); + } + else if (PPLogger.getTotalInstrs() == 0) + { + printf("Not using fake intrinsics in ClampedExp\n"); + } + else + { + printf("ClampedExp Passed!!!\n"); + } + + PPLogger.refresh(); + + printf("\n\e[1;31mARRAY SUM\e[0m (bonus) \n"); + if (N % VECTOR_WIDTH == 0) + { + float sumGold = arraySumSerial(values, N); + float sumOutput = arraySumVector(values, N); + + if (printLog) + PPLogger.printLog(); + PPLogger.printStats(); + + printf("************************ Result Verification *************************\n"); + + float epsilon = 0.1; + bool sumCorrect = abs(sumGold - sumOutput) < epsilon * 2; + if (!sumCorrect) + { + printf("Expected %f, got %f\n.", sumGold, sumOutput); + printf("@@@ ArraySum Failed!!!\n"); + } + else if (PPLogger.getTotalInstrs() == 0) + { + printf("Not using fake intrinsics in ArraySum\n"); + } + else + { + printf("ArraySum Passed!!!\n"); + } + } + else + { + printf("Must have N %% VECTOR_WIDTH == 0 for this problem (VECTOR_WIDTH is %d)\n", VECTOR_WIDTH); + } + + delete[] values; + delete[] exponents; + delete[] output; + delete[] gold; + + return 0; +} + +void usage(const char *progname) +{ + printf("Usage: %s [options]\n", progname); + printf("Program Options:\n"); + printf(" -s --size Use workload size N (Default = 16)\n"); + printf(" -l --log Print vector unit execution log\n"); + printf(" -? --help This message\n"); +} + +void initValue(float *values, int *exponents, float *output, float *gold, unsigned int N) +{ + + for (unsigned int i = 0; i < N + VECTOR_WIDTH; i++) + { + // random input values + values[i] = -1.f + 4.f * static_cast(rand()) / RAND_MAX; + exponents[i] = rand() % EXP_MAX; + output[i] = 0.f; + gold[i] = 0.f; + } +} + +bool verifyResult(float *values, int *exponents, float *output, float *gold, int N) +{ + int incorrect = -1; + float epsilon = 0.00001; + for (int i = 0; i < N + VECTOR_WIDTH; i++) + { + if (abs(output[i] - gold[i]) > epsilon) + { + incorrect = i; + break; + } + } + + if (incorrect != -1) + { + if (incorrect >= N) + printf("You have written to out of bound value!\n"); + printf("Wrong calculation at value[%d]!\n", incorrect); + printf("value = "); + for (int i = 0; i < N; i++) + { + printf("% f ", values[i]); + } + printf("\n"); + + printf("exp = "); + for (int i = 0; i < N; i++) + { + printf("% 9d ", exponents[i]); + } + printf("\n"); + + printf("output = "); + for (int i = 0; i < N; i++) + { + printf("% f ", output[i]); + } + printf("\n"); + + printf("gold = "); + for (int i = 0; i < N; i++) + { + printf("% f ", gold[i]); + } + printf("\n"); + return false; + } + printf("Results matched with answer!\n"); + return true; +} diff --git a/part1/myexp b/part1/myexp new file mode 100755 index 0000000000000000000000000000000000000000..ea305aec02a9dc84ac9fee00ee94f03f5a679098 GIT binary patch literal 38472 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 literal 0 HcmV?d00001 diff --git a/part1/serialOP.cpp b/part1/serialOP.cpp new file mode 100644 index 0000000..363fa8e --- /dev/null +++ b/part1/serialOP.cpp @@ -0,0 +1,61 @@ +// computes the absolute value of all elements in the input array +// values, stores result in output +void absSerial(float *values, float *output, int N) +{ + for (int i = 0; i < N; i++) + { + float x = values[i]; + if (x < 0) + { + output[i] = -x; + } + else + { + output[i] = x; + } + } +} + +// accepts an array of values and an array of exponents +// +// For each element, compute values[i]^exponents[i] and clamp value to +// 9.999. Store result in output. +void clampedExpSerial(float *values, int *exponents, float *output, int N) +{ + for (int i = 0; i < N; i++) + { + float x = values[i]; + int y = exponents[i]; + if (y == 0) + { + output[i] = 1.f; + } + else + { + float result = x; + int count = y - 1; + while (count > 0) + { + result *= x; + count--; + } + if (result > 9.999999f) + { + result = 9.999999f; + } + output[i] = result; + } + } +} + +// returns the sum of all elements in values +float arraySumSerial(float *values, int N) +{ + float sum = 0; + for (int i = 0; i < N; i++) + { + sum += values[i]; + } + + return sum; +} \ No newline at end of file diff --git a/part1/vectorOP.cpp b/part1/vectorOP.cpp new file mode 100644 index 0000000..e3f943a --- /dev/null +++ b/part1/vectorOP.cpp @@ -0,0 +1,72 @@ +#include "PPintrin.h" + +// implementation of absSerial(), but it is vectorized using PP intrinsics +void absVector(float *values, float *output, int N) +{ + __pp_vec_float x; + __pp_vec_float result; + __pp_vec_float zero = _pp_vset_float(0.f); + __pp_mask maskAll, maskIsNegative, maskIsNotNegative; + + // Note: Take a careful look at this loop indexing. This example + // code is not guaranteed to work when (N % VECTOR_WIDTH) != 0. + // Why is that the case? + for (int i = 0; i < N; i += VECTOR_WIDTH) + { + + // All ones + maskAll = _pp_init_ones(); + + // All zeros + maskIsNegative = _pp_init_ones(0); + + // Load vector of values from contiguous memory addresses + _pp_vload_float(x, values + i, maskAll); // x = values[i]; + + // Set mask according to predicate + _pp_vlt_float(maskIsNegative, x, zero, maskAll); // if (x < 0) { + + // Execute instruction using mask ("if" clause) + _pp_vsub_float(result, zero, x, maskIsNegative); // output[i] = -x; + + // Inverse maskIsNegative to generate "else" mask + maskIsNotNegative = _pp_mask_not(maskIsNegative); // } else { + + // Execute instruction ("else" clause) + _pp_vload_float(result, values + i, maskIsNotNegative); // output[i] = x; } + + // Write results back to memory + _pp_vstore_float(output + i, result, maskAll); + } +} + +void clampedExpVector(float *values, int *exponents, float *output, int N) +{ + // + // PP STUDENTS TODO: Implement your vectorized version of + // clampedExpSerial() here. + // + // Your solution should work for any value of + // N and VECTOR_WIDTH, not just when VECTOR_WIDTH divides N + // + for (int i = 0; i < N; i += VECTOR_WIDTH) + { + } +} + +// returns the sum of all elements in values +// You can assume N is a multiple of VECTOR_WIDTH +// You can assume VECTOR_WIDTH is a power of 2 +float arraySumVector(float *values, int N) +{ + + // + // PP STUDENTS TODO: Implement your vectorized version of arraySumSerial here + // + + for (int i = 0; i < N; i += VECTOR_WIDTH) + { + } + + return 0.0; +} \ No newline at end of file diff --git a/part2/Makefile b/part2/Makefile new file mode 100644 index 0000000..7b4a698 --- /dev/null +++ b/part2/Makefile @@ -0,0 +1,53 @@ +TARGET := test_auto_vectorize + +OBJS := main.o test1.o test2.o test3.o + +CC := clang + +CFLAGS := -O3 -std=c11 -Wall -D_POSIX_C_SOURCE=200809L + +ifeq ($(ASSEMBLE),1) + CFLAGS += -S +endif +ifeq ($(VECTORIZE),1) + CFLAGS += -Rpass=loop-vectorize -Rpass-missed=loop-vectorize -Rpass-analysis=loop-vectorize + SUFFIX := .vec +else + CFLAGS += -fno-vectorize + SUFFIX := .novec +endif +ifeq ($(RESTRICT),1) + SUFFIX := $(SUFFIX).restr +endif +ifeq ($(ALIGN),1) + SUFFIX := $(SUFFIX).align +endif +ifeq ($(AVX2),1) + CFLAGS += -mavx2 + SUFFIX := $(SUFFIX).avx2 +endif +ifeq ($(FASTMATH),1) + CFLAGS += -ffast-math + SUFFIX := $(SUFFIX).fmath +endif + +all: $(TARGET) + +%.o: %.c test.h +ifeq ($(ASSEMBLE),1) + mkdir -p "./assembly" + $(CC) $(CFLAGS) -c $< -o assembly/$(basename $<)$(SUFFIX).s +else + $(CC) $(CFLAGS) -c $< +endif + +$(TARGET): $(OBJS) +ifneq ($(ASSEMBLE),1) + $(CC) $(CFLAGS) $(OBJS) -o $@ +endif + +clean: + $(RM) *.o *.s $(TARGET) *~ + +cleanall: + $(RM) -r *.o *.s $(TARGET) *~ assembly diff --git a/part2/fasttime.h b/part2/fasttime.h new file mode 100644 index 0000000..f12c856 --- /dev/null +++ b/part2/fasttime.h @@ -0,0 +1,97 @@ +/** + * Copyright (c) 2014 MIT License by 6.172 Staff + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + **/ + +#ifndef INCLUDED_FASTTIME_DOT_H +#define INCLUDED_FASTTIME_DOT_H + +#define _POSIX_C_SOURCE 200809L + +#include + +#ifdef __MACH__ +#include // mach_absolute_time + +typedef uint64_t fasttime_t; + + +// Return the current time. +static inline fasttime_t gettime(void) { + return mach_absolute_time(); +} + +// Return the time different between the start and the end, as a float +// in units of seconds. This function does not need to be fast. +// Implementation notes: See +// https://developer.apple.com/library/mac/qa/qa1398/_index.html +static inline double tdiff(fasttime_t start, fasttime_t end) { + static mach_timebase_info_data_t timebase; + int r = mach_timebase_info(&timebase); + assert(r == 0); + fasttime_t elapsed = end-start; + double ns = (double)elapsed * timebase.numer / timebase.denom; + return ns*1e-9; +} + +static inline unsigned int random_seed_from_clock(void) { + fasttime_t now = gettime(); + return (now & 0xFFFFFFFF) + (now>>32); +} + +#else // LINUX + +// We need _POSIX_C_SOURCE to pick up 'struct timespec' and clock_gettime. +// #define _POSIX_C_SOURCE 200809L + +#include + +typedef struct timespec fasttime_t; + +// Return the current time. +static inline fasttime_t gettime(void) { + struct timespec s; +#ifdef NDEBUG + clock_gettime(CLOCK_MONOTONIC, &s); +#else + int r = clock_gettime(CLOCK_MONOTONIC, &s); + assert(r == 0); +#endif + return s; +} + +// Return the time different between the start and the end, as a float +// in units of seconds. This function does not need to be fast. +static inline double tdiff(fasttime_t start, fasttime_t end) { + return end.tv_sec - start.tv_sec + 1e-9*(end.tv_nsec - start.tv_nsec); +} + +static inline unsigned int random_seed_from_clock(void) { + fasttime_t now = gettime(); + return now.tv_sec + now.tv_nsec; +} + +// Poison these symbols to help find portability problems. +int clock_gettime(clockid_t, struct timespec *) __attribute__((deprecated)); +time_t time(time_t *) __attribute__((deprecated)); + +#endif // LINUX + +#endif // INCLUDED_FASTTIME_DOT_H diff --git a/part2/main.c b/part2/main.c new file mode 100644 index 0000000..939b186 --- /dev/null +++ b/part2/main.c @@ -0,0 +1,91 @@ +#include +#include +#include +#include "fasttime.h" +#include "test.h" + +void usage(const char *progname); +void initValue(float *values1, float *values2, double *value3, float *output, unsigned int N); + +extern void test1(float *a, float *b, float *c, int N); +extern void test2(float *__restrict a, float *__restrict b, float *__restrict c, int N); +extern double test3(double *__restrict a, int N) ; + +int main(int argc, char **argv) { + int N = 1024; + int whichTestToRun = 1; + + // parse commandline options + int opt; + static struct option long_options[] = { + {"size", 1, 0, 's'}, + {"test", 1, 0, 't'}, + {"help", 0, 0, '?'}, + {0 ,0, 0, 0} + }; + + while ((opt = getopt_long(argc, argv, "st:?", long_options, NULL)) != EOF) { + + switch (opt) { + case 's': + N = atoi(optarg); + if (N <= 0) { + printf("Error: Workload size is set to %d (<0).\n", N); + return -1; + } + break; + case 't': + whichTestToRun = atoi(optarg); + if (whichTestToRun <= 0 || whichTestToRun >= 4) { + printf("Error: test%d() is not available.\n", whichTestToRun); + return -1; + } + break; + case 'h': + default: + usage(argv[0]); + return 1; + } + } + +#define AVX_ALIGNMENT 256 + float *values1 = (float *)__builtin_alloca_with_align(N * sizeof(float), AVX_ALIGNMENT); + float *values2 = (float *)__builtin_alloca_with_align(N * sizeof(float), AVX_ALIGNMENT); + double *values3 = (double *)__builtin_alloca_with_align(N * sizeof(double), AVX_ALIGNMENT); + float *output = (float *)__builtin_alloca_with_align(N * sizeof(float), AVX_ALIGNMENT); +#undef AVX_ALIGNMENT + initValue(values1, values2, values3, output, N); + + printf("Running test%d()...\n", whichTestToRun); + fasttime_t time1 = gettime(); + switch (whichTestToRun) { + case 1: test1(values1, values2, output, N); break; + case 2: test2(values1, values2, output, N); break; + case 3: test3(values3, N); break; + } + fasttime_t time2 = gettime(); + + double elapsedf = tdiff(time1, time2); + printf("Elapsed execution time of the loop in test%d():\n", whichTestToRun); + printf("%lfsec (N: %d, I: %d)\n", elapsedf, N, I); + return 0; +} + +void usage(const char *progname) { + printf("Usage: %s [options]\n", progname); + printf("Program Options:\n"); + printf(" -s --size Use workload size N (Default = 1024)\n"); + printf(" -t --test Just run the testN function (Default = 1)\n"); + printf(" -h --help This message\n"); +} + +void initValue(float *values1, float *values2, double *values3, float *output, unsigned int N) { + for (unsigned int i=0; i a[j]) + c[j] = b[j]; + } + } +} diff --git a/part2/test2.c.patch b/part2/test2.c.patch new file mode 100644 index 0000000..67b5857 --- /dev/null +++ b/part2/test2.c.patch @@ -0,0 +1,13 @@ +--- test2.c ++++ test2.c +@@ -14,9 +14,8 @@ + for (int j = 0; j < N; j++) + { + /* max() */ +- c[j] = a[j]; +- if (b[j] > a[j]) +- c[j] = b[j]; ++ if (b[j] > a[j]) c[j] = b[j]; ++ else c[j] = a[j]; + } + } diff --git a/part2/test3.c b/part2/test3.c new file mode 100644 index 0000000..05a3468 --- /dev/null +++ b/part2/test3.c @@ -0,0 +1,14 @@ +#include "test.h" + +double test3(double *__restrict a, int N) { + __builtin_assume(N == 1024); + a = (double *)__builtin_assume_aligned(a, 16); + + double b = 0; + for (int i=0; i