From 4dadbdf4b39c8b70784f110b984897261221f37f Mon Sep 17 00:00:00 2001 From: Jan Eitzinger Date: Wed, 13 Mar 2019 14:41:11 +0100 Subject: [PATCH] Add affinity module. Enable configuration in config.mk file. Introduce timer resolution report. --- Makefile | 4 +- config.mk | 6 +++ src/affinity.c | 85 +++++++++++++++++++++++++++++++++++++++++ src/includes/affinity.h | 36 +++++++++++++++++ src/main.c | 83 +++++++++++++++++++++++++--------------- src/sum.c | 2 +- 6 files changed, 183 insertions(+), 33 deletions(-) create mode 100644 config.mk create mode 100644 src/affinity.c create mode 100644 src/includes/affinity.h diff --git a/Makefile b/Makefile index 728522f..dacc79c 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,7 @@ Q ?= @ #DO NOT EDIT BELOW include $(MAKE_DIR)/include_$(TAG).mk +include $(MAKE_DIR)/config.mk INCLUDES += -I./src/includes VPATH = $(SRC_DIR) @@ -20,7 +21,7 @@ OBJ += $(patsubst $(SRC_DIR)/%.cc, $(BUILD_DIR)/%.o,$(wildcard $(SRC_DIR)/* OBJ += $(patsubst $(SRC_DIR)/%.cpp, $(BUILD_DIR)/%.o,$(wildcard $(SRC_DIR)/*.cpp)) OBJ += $(patsubst $(SRC_DIR)/%.f90, $(BUILD_DIR)/%.o,$(wildcard $(SRC_DIR)/*.f90)) OBJ += $(patsubst $(SRC_DIR)/%.F90, $(BUILD_DIR)/%.o,$(wildcard $(SRC_DIR)/*.F90)) -CPPFLAGS := $(CPPFLAGS) $(DEFINES) $(INCLUDES) +CPPFLAGS := $(CPPFLAGS) $(DEFINES) $(OPTIONS) $(INCLUDES) ${TARGET}: $(BUILD_DIR) $(OBJ) @@ -64,7 +65,6 @@ tags: @echo "===> GENERATE TAGS" $(Q)ctags -R - $(BUILD_DIR): @mkdir $(BUILD_DIR) diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..da8c763 --- /dev/null +++ b/config.mk @@ -0,0 +1,6 @@ +OPTIONS = -DSIZE=40000000ull +OPTIONS += -DNTIMES=10 +OPTIONS += -DARRAY_ALIGNMENT=64 +#OPTIONS += -DVERBOSE_AFFINITY +#OPTIONS += -DVERBOSE_DATASIZE +#OPTIONS += -DVERBOSE_TIMER diff --git a/src/affinity.c b/src/affinity.c new file mode 100644 index 0000000..2ccd079 --- /dev/null +++ b/src/affinity.c @@ -0,0 +1,85 @@ +/* + * ======================================================================================= + * + * Author: Jan Eitzinger (je), jan.treibig@gmail.com + * Copyright (c) 2019 RRZE, University Erlangen-Nuremberg + * + * 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.#include + * + * ======================================================================================= + */ + +#include +#include +#include +#include +#include +#include +#include + +#define MAX_NUM_THREADS 128 +#define gettid() syscall(SYS_gettid) + +static int +getProcessorID(cpu_set_t* cpu_set) +{ + int processorId; + + for ( processorId = 0; processorId < MAX_NUM_THREADS; processorId++ ) + { + if ( CPU_ISSET(processorId,cpu_set) ) + { + break; + } + } + return processorId; +} + + +int +affinity_getProcessorId() +{ + cpu_set_t cpu_set; + CPU_ZERO(&cpu_set); + sched_getaffinity(gettid(),sizeof(cpu_set_t), &cpu_set); + + return getProcessorID(&cpu_set); +} + +void +affinity_pinThread(int processorId) +{ + cpu_set_t cpuset; + pthread_t thread; + + thread = pthread_self(); + CPU_ZERO(&cpuset); + CPU_SET(processorId, &cpuset); + pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset); +} + +void +affinity_pinProcess(int processorId) +{ + cpu_set_t cpuset; + + CPU_ZERO(&cpuset); + CPU_SET(processorId, &cpuset); + sched_setaffinity(0, sizeof(cpu_set_t), &cpuset); +} diff --git a/src/includes/affinity.h b/src/includes/affinity.h new file mode 100644 index 0000000..3c18595 --- /dev/null +++ b/src/includes/affinity.h @@ -0,0 +1,36 @@ +/* + * ======================================================================================= + * + * Author: Jan Eitzinger (je), jan.treibig@gmail.com + * Copyright (c) 2019 RRZE, University Erlangen-Nuremberg + * + * 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.#include + * + * ======================================================================================= + */ + +#ifndef AFFINITY_H +#define AFFINITY_H + +extern int affinity_getProcessorId(); +extern void affinity_pinProcess(int); +extern void affinity_pinThread(int); + +#endif /*AFFINITY_H*/ + diff --git a/src/main.c b/src/main.c index 7d9efae..72e483c 100644 --- a/src/main.c +++ b/src/main.c @@ -35,13 +35,11 @@ #include #endif +#include #include +#include -#define ARRAY_ALIGNMENT 64 -#define SIZE 20000000ull -#define NTIMES 10 - -# define HLINE "-------------------------------------------------------------\n" +#define HLINE "----------------------------------------------------------------------------\n" #ifndef MIN #define MIN(x,y) ((x)<(y)?(x):(y)) @@ -65,6 +63,12 @@ typedef enum benchmark { NUMBENCH } benchmark; +typedef struct { + char* label; + int words; + int flops; +} benchmarkType; + extern double init(double*, double, int); extern double sum(double*, int); extern double copy(double*, double*, int); @@ -82,6 +86,7 @@ int main (int argc, char** argv) size_t N = SIZE; double *a, *b, *c, *d; double scalar, tmp; + double E, S; double avgtime[NUMBENCH], maxtime[NUMBENCH], @@ -89,33 +94,29 @@ int main (int argc, char** argv) double times[NUMBENCH][NTIMES]; - double bytes[NUMBENCH] = { - 1 * sizeof(double) * N, /* init */ - 1 * sizeof(double) * N, /* sum */ - 2 * sizeof(double) * N, /* copy */ - 2 * sizeof(double) * N, /* update */ - 3 * sizeof(double) * N, /* triad */ - 3 * sizeof(double) * N, /* daxpy */ - 4 * sizeof(double) * N, /* striad */ - 4 * sizeof(double) * N /* sdaxpy */ + benchmarkType benchmarks[NUMBENCH] = { + {"Init: ", 1, 0}, + {"Sum: ", 1, 1}, + {"Copy: ", 2, 0}, + {"Update: ", 2, 1}, + {"Triad: ", 3, 2}, + {"Daxpy: ", 3, 2}, + {"STriad: ", 4, 2}, + {"SDaxpy: ", 4, 2} }; - char *label[NUMBENCH] = { - "Init: ", - "Sum: ", - "Copy: ", - "Update: ", - "Triad: ", - "Daxpy: ", - "STriad: ", - "SDaxpy: "}; - a = (double*) allocate( ARRAY_ALIGNMENT, N * bytesPerWord ); b = (double*) allocate( ARRAY_ALIGNMENT, N * bytesPerWord ); c = (double*) allocate( ARRAY_ALIGNMENT, N * bytesPerWord ); d = (double*) allocate( ARRAY_ALIGNMENT, N * bytesPerWord ); + printf(HLINE); + printf ("Total allocated datasize: %8.2f MB\n", 4.0 * bytesPerWord * N * 1.0E-06); + for (int i=0; i 0){ + printf("%s%11.2f %11.2f %11.4f %11.4f %11.4f\n", benchmarks[j].label, + 1.0E-06 * bytes/mintime[j], + 1.0E-06 * flops/mintime[j], + avgtime[j], + mintime[j], + maxtime[j]); + } else { + printf("%s%11.2f - %11.4f %11.4f %11.4f\n", benchmarks[j].label, + 1.0E-06 * bytes/mintime[j], + avgtime[j], + mintime[j], + maxtime[j]); + } } printf(HLINE); diff --git a/src/sum.c b/src/sum.c index b31074b..75d23a7 100644 --- a/src/sum.c +++ b/src/sum.c @@ -36,7 +36,7 @@ double sum( double sum = 0.0; S = getTimeStamp(); -#pragma omp parallel for simd reduction(+:sum) +#pragma omp parallel for reduction(+:sum) for (int i=0; i