diff --git a/Makefile.in b/Makefile.in index ea71c6bcd..81ee25c15 100644 --- a/Makefile.in +++ b/Makefile.in @@ -11,6 +11,7 @@ instbasedir := $(DESTDIR)$(prefix) bmarkdir := $(abs_top_src_dir)/benchmarks isa_src_dir := $(abs_top_src_dir)/isa debug_src_dir := $(abs_top_src_dir)/debug +enable_multi_threads := @MULTI_THREADS@ all: benchmarks isa diff --git a/benchmarks/Makefile b/benchmarks/Makefile index fb0d2977d..698d5c2ff 100644 --- a/benchmarks/Makefile +++ b/benchmarks/Makefile @@ -43,7 +43,7 @@ RISCV_LINK_OPTS ?= -static -nostdlib -nostartfiles -lm -lgcc -T $(src_dir)/commo RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump --disassemble-all --disassemble-zeroes --section=.text --section=.text.startup --section=.data RISCV_SIM ?= spike --isa=rv$(XLEN)gc -incs += -I$(src_dir)/../env -I$(src_dir)/common $(addprefix -I$(src_dir)/, $(bmarks)) +incs += -I$(src_dir)/../env -I$(src_dir)/common -I$(src_dir)/../ $(addprefix -I$(src_dir)/, $(bmarks)) objs := define compile_template diff --git a/benchmarks/common/crt.S b/benchmarks/common/crt.S index d75e81e06..10d6a9572 100644 --- a/benchmarks/common/crt.S +++ b/benchmarks/common/crt.S @@ -1,6 +1,7 @@ # See LICENSE for license details. #include "encoding.h" +#include "config.h" #if __riscv_xlen == 64 # define LREG ld diff --git a/benchmarks/common/syscalls.c b/benchmarks/common/syscalls.c index 0a7d6b728..2c8c5a93a 100644 --- a/benchmarks/common/syscalls.c +++ b/benchmarks/common/syscalls.c @@ -95,13 +95,15 @@ int __attribute__((weak)) main(int argc, char** argv) static void init_tls() { +#if ENABLE_THREADS register void* thread_pointer asm("tp"); extern char _tls_data; - extern __thread char _tdata_begin, _tdata_end, _tbss_end; + extern THREAD_LOCAL char _tdata_begin, _tdata_end, _tbss_end; size_t tdata_size = &_tdata_end - &_tdata_begin; memcpy(thread_pointer, &_tls_data, tdata_size); size_t tbss_size = &_tbss_end - &_tdata_end; memset(thread_pointer + tdata_size, 0, tbss_size); +#endif } void _init(int cid, int nc) @@ -126,8 +128,8 @@ void _init(int cid, int nc) #undef putchar int putchar(int ch) { - static __thread char buf[64] __attribute__((aligned(64))); - static __thread int buflen = 0; + static THREAD_LOCAL char buf[64] __attribute__((aligned(64))); + static THREAD_LOCAL int buflen = 0; buf[buflen++] = ch; diff --git a/benchmarks/common/util.h b/benchmarks/common/util.h index 081cfd634..da894d436 100644 --- a/benchmarks/common/util.h +++ b/benchmarks/common/util.h @@ -6,9 +6,20 @@ extern void setStats(int enable); #include +#include "config.h" #define static_assert(cond) switch(0) { case 0: case !!(long)(cond): ; } +#ifndef ENABLE_THREADS +#define ENABLE_THREADS 1 +#endif + +#if ENABLE_THREADS +#define THREAD_LOCAL __thread +#else +#define THREAD_LOCAL +#endif + static int verify(int n, const volatile int* test, const int* verify) { int i; @@ -45,7 +56,7 @@ static void __attribute__((noinline)) barrier(int ncores) { static volatile int sense; static volatile int count; - static __thread int threadsense; + static THREAD_LOCAL int threadsense; __sync_synchronize(); diff --git a/config.in b/config.in new file mode 100644 index 000000000..74e9bb2e8 --- /dev/null +++ b/config.in @@ -0,0 +1,22 @@ +/* config.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you want to test with multi-thread. */ +#undef ENABLE_THREADS + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION diff --git a/configure b/configure index db0969e93..6464c3651 100755 --- a/configure +++ b/configure @@ -633,6 +633,7 @@ ac_subst_files='' ac_user_opts=' enable_option_checking with_xlen +enable_threads ' ac_precious_vars='build_alias host_alias @@ -1247,6 +1248,12 @@ if test -n "$ac_init_help"; then esac cat <<\_ACEOF +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-threads enable test for multi-thread. + Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) @@ -2534,6 +2541,27 @@ else fi +ac_enable_threads=unset +# Check whether --enable-threads was given. +if test "${enable_threads+set}" = set; then : + enableval=$enable_threads; case "${enableval}" in + yes) ac_enable_threads=1 ;; + no) ac_enable_threads=0 ;; +esac +fi + +if test "${ac_enable_threads}" = unset; then + ac_enable_threads=1 +fi + + +cat >>confdefs.h <<_ACEOF +#define ENABLE_THREADS $ac_enable_threads +_ACEOF + + +ac_config_headers="$ac_config_headers config.h:config.in" + ac_config_files="$ac_config_files Makefile" @@ -2627,43 +2655,7 @@ test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' -# Transform confdefs.h into DEFS. -# Protect against shell expansion while executing Makefile rules. -# Protect against Makefile macro expansion. -# -# If the first sed substitution is executed (which looks for macros that -# take arguments), then branch to the quote section. Otherwise, -# look for a macro that doesn't take arguments. -ac_script=' -:mline -/\\$/{ - N - s,\\\n,, - b mline -} -t clear -:clear -s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g -t quote -s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g -t quote -b any -:quote -s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g -s/\[/\\&/g -s/\]/\\&/g -s/\$/$$/g -H -:any -${ - g - s/^\n// - s/\n/ /g - p -} -' -DEFS=`sed -n "$ac_script" confdefs.h` - +DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= @@ -3097,11 +3089,15 @@ case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" +config_headers="$ac_config_headers" _ACEOF @@ -3122,10 +3118,15 @@ Usage: $0 [OPTION]... [TAG]... --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE Configuration files: $config_files +Configuration headers: +$config_headers + Report bugs to the package provider." _ACEOF @@ -3186,7 +3187,18 @@ do esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; - --he | --h | --help | --hel | -h ) + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) @@ -3242,6 +3254,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 for ac_config_target in $ac_config_targets do case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h:config.in" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; @@ -3255,6 +3268,7 @@ done # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree @@ -3442,8 +3456,116 @@ fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. -eval set X " :F $CONFIG_FILES " +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " shift for ac_tag do @@ -3651,7 +3773,30 @@ which seems to be undefined. Please make sure it is defined" >&2;} esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; - + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi + ;; esac diff --git a/configure.ac b/configure.ac index ebfd64979..9114632ae 100644 --- a/configure.ac +++ b/configure.ac @@ -10,6 +10,24 @@ AC_ARG_WITH(xlen, AC_SUBST(XLEN, 64) ) +ac_enable_threads=unset +AC_ARG_ENABLE(threads, + AS_HELP_STRING([--enable-threads], + [enable test for multi-thread.]), +[case "${enableval}" in + yes) ac_enable_threads=1 ;; + no) ac_enable_threads=0 ;; +esac])dnl + +if test "${ac_enable_threads}" = unset; then + ac_enable_threads=1 +fi + +AC_DEFINE_UNQUOTED(ENABLE_THREADS, + $ac_enable_threads, + [Define to 1 if you want to test with multi-thread.]) + +AC_CONFIG_HEADERS(config.h:config.in) AC_OUTPUT( Makefile diff --git a/mt/av_matmul.c b/mt/av_matmul.c index 0f0dbaed2..381e4f827 100644 --- a/mt/av_matmul.c +++ b/mt/av_matmul.c @@ -9,10 +9,10 @@ void __attribute__((noinline)) matmul(const int coreid, const int ncores, const //-----------------------------------------------------------------version 2.16, optimize v2.15 get rid of tempb. MSI 83K.w/ test one 81K. - static __thread data_t TempA[8]; - static __thread data_t TempB[8]; - static __thread data_t TempC[8]; - static __thread int j,m,n; + static THREAD_LOCAL data_t TempA[8]; + static THREAD_LOCAL data_t TempB[8]; + static THREAD_LOCAL data_t TempC[8]; + static THREAD_LOCAL int j,m,n; if(coreid == 1 || ncores == 1 ) { diff --git a/mt/ay_matmul.c b/mt/ay_matmul.c index 45fb19425..949285754 100644 --- a/mt/ay_matmul.c +++ b/mt/ay_matmul.c @@ -6,11 +6,11 @@ void __attribute__((noinline)) matmul(const int coreid, const int ncores, const int lda, const data_t A[], const data_t B[], data_t C[] ) { if(coreid > 1) return; - static __thread int i, j, k; - static __thread data_t tempA0, tempA1, tempA2, tempA3, tempA4, tempA5, tempA6, tempA7; - static __thread data_t tempC0, tempC1, tempC2, tempC3, tempC4, tempC5, tempC6, tempC7, tempC8, tempC9, tempC10, tempC11, tempC12, tempC13, tempC14, tempC15; + static THREAD_LOCAL int i, j, k; + static THREAD_LOCAL data_t tempA0, tempA1, tempA2, tempA3, tempA4, tempA5, tempA6, tempA7; + static THREAD_LOCAL data_t tempC0, tempC1, tempC2, tempC3, tempC4, tempC5, tempC6, tempC7, tempC8, tempC9, tempC10, tempC11, tempC12, tempC13, tempC14, tempC15; - static __thread int start, end, jStride, jToRow, jToCol; + static THREAD_LOCAL int start, end, jStride, jToRow, jToCol; start = coreid << 9; end = ((ncores == 1) ? 2 : (coreid+1) ) << 9; diff --git a/mt/az_matmul.c b/mt/az_matmul.c index 1668fb019..2679558bb 100644 --- a/mt/az_matmul.c +++ b/mt/az_matmul.c @@ -7,11 +7,11 @@ void __attribute__((noinline)) matmul(const int coreid, const int ncores, const { if(coreid > 1) return; - static __thread int i, j, k; - static __thread data_t tempA0, tempA1, tempA2, tempA3, tempA4, tempA5, tempA6, tempA7; - static __thread data_t tempC0, tempC1, tempC2, tempC3, tempC4, tempC5, tempC6, tempC7; //tempC8, tempC9, tempC10, tempC11, tempC12, tempC13, tempC14, tempC15; + static THREAD_LOCAL int i, j, k; + static THREAD_LOCAL data_t tempA0, tempA1, tempA2, tempA3, tempA4, tempA5, tempA6, tempA7; + static THREAD_LOCAL data_t tempC0, tempC1, tempC2, tempC3, tempC4, tempC5, tempC6, tempC7; //tempC8, tempC9, tempC10, tempC11, tempC12, tempC13, tempC14, tempC15; - static __thread int start, end, jStride, jToRow, jToCol, iToRow; + static THREAD_LOCAL int start, end, jStride, jToRow, jToCol, iToRow; start = coreid << 9; end = ((ncores == 1) ? 2 : (coreid+1)) << 9; diff --git a/mt/br_matmul.c b/mt/br_matmul.c index 13263e4f9..b3f7361bc 100644 --- a/mt/br_matmul.c +++ b/mt/br_matmul.c @@ -17,7 +17,7 @@ void __attribute__((noinline)) matmul(const int coreid, const int ncores, const int jBLOCK = 32; int iBLOCK = 16; int kBLOCK = 32; - static __thread int tB[4096]; //__thread + static THREAD_LOCAL int tB[4096]; //THREAD_LOCAL int startInd = coreid*(lda/ncores); int endInd = (coreid+1)*(lda/ncores); diff --git a/mt/cv_matmul.c b/mt/cv_matmul.c index 2a0691940..5ec0984ad 100644 --- a/mt/cv_matmul.c +++ b/mt/cv_matmul.c @@ -7,9 +7,9 @@ void __attribute__((noinline)) matmul(const int coreid, const int ncores, const { //----------------------------------------------------------------version 2.11 optmize j,use core 1 j from 0 to 15 MSI 98k i = j*lda //----------------------------------------------------------------version 2.12 not use i = j *lda MSI 95k - static __thread data_t TempA[8]; - static __thread data_t TempB[8]; - static __thread int j,m,n,i,k; + static THREAD_LOCAL data_t TempA[8]; + static THREAD_LOCAL data_t TempB[8]; + static THREAD_LOCAL int j,m,n,i,k; if(coreid == 1 || ncores == 1) { diff --git a/mt/cy_matmul.c b/mt/cy_matmul.c index b0713cd43..a758952ad 100644 --- a/mt/cy_matmul.c +++ b/mt/cy_matmul.c @@ -6,11 +6,11 @@ void __attribute__((noinline)) matmul(const int coreid, const int ncores, const int lda, const data_t A[], const data_t B[], data_t C[] ) { if(coreid > 1) return; - static __thread int i, j, k; - static __thread data_t tempA0, tempA1, tempA2, tempA3, tempA4, tempA5, tempA6, tempA7; - static __thread data_t tempC0, tempC1, tempC2, tempC3, tempC4, tempC5, tempC6, tempC7, tempC8, tempC9, tempC10, tempC11, tempC12, tempC13, tempC14, tempC15; + static THREAD_LOCAL int i, j, k; + static THREAD_LOCAL data_t tempA0, tempA1, tempA2, tempA3, tempA4, tempA5, tempA6, tempA7; + static THREAD_LOCAL data_t tempC0, tempC1, tempC2, tempC3, tempC4, tempC5, tempC6, tempC7, tempC8, tempC9, tempC10, tempC11, tempC12, tempC13, tempC14, tempC15; - static __thread int start, end, jStride, jToRow, jToCol; + static THREAD_LOCAL int start, end, jStride, jToRow, jToCol; static data_t A1[1024], B1[1024];; start = coreid << 9; diff --git a/mt/dr_matmul.c b/mt/dr_matmul.c index 8a3d57ce1..c59722d72 100644 --- a/mt/dr_matmul.c +++ b/mt/dr_matmul.c @@ -17,7 +17,7 @@ void __attribute__((noinline)) matmul(const int coreid, const int ncores, const int jBLOCK = 32; int iBLOCK = 16; int kBLOCK = 32; - static __thread int tB[4096]; //__thread + static THREAD_LOCAL int tB[4096]; //THREAD_LOCAL int startInd = coreid*(lda/ncores); int endInd = (coreid+1)*(lda/ncores);