diff --git a/doc/binary_c2.lyx b/doc/binary_c2.lyx index 126e83e3ac3abc7ceb64960fe2fb73a4a24ba820..ebf54e58877ce6290f9ec91458755b7f194ff064 100644 --- a/doc/binary_c2.lyx +++ b/doc/binary_c2.lyx @@ -3919,6 +3919,91 @@ pip3 install meson \end_inset which should get you the latest version. +\begin_inset Newline newline +\end_inset + + +\begin_inset Newline newline +\end_inset + +Note: +\begin_inset Flex Software +status open + +\begin_layout Plain Layout +emacs +\end_layout + +\end_inset + + users should install the meson-mode. + Go to +\begin_inset CommandInset href +LatexCommand href +target "https://github.com/wentasah/meson-mode" +literal "false" + +\end_inset + + and download +\begin_inset Flex File +status open + +\begin_layout Plain Layout +meson-mode.el +\end_layout + +\end_inset + + to your +\begin_inset Flex File +status open + +\begin_layout Plain Layout +~/.emacs-el +\end_layout + +\end_inset + + directory. + In your +\begin_inset Flex File +status open + +\begin_layout Plain Layout +~/.emacs +\end_layout + +\end_inset + + file add the following. +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +; meson support +\end_layout + +\begin_layout Plain Layout + +(load "~/.emacs-el/meson-mode.el") +\end_layout + +\end_inset + +You can edit the +\begin_inset Flex File +status open + +\begin_layout Plain Layout +meson-mode.el +\end_layout + +\end_inset + + to suit your needs: I changed the indentation from 2 to 4, for example. \end_layout \begin_layout Itemize @@ -4092,6 +4177,32 @@ gdb . \end_layout +\begin_layout Itemize +I highly recommend the use of +\begin_inset Flex Software +status open + +\begin_layout Plain Layout + +\emph off +ccache +\end_layout + +\end_inset + + to speed up builds. + You can usually install this as a system package, or see +\begin_inset CommandInset href +LatexCommand href +name "the ccache homepage" +target "https://ccache.dev/" +literal "false" + +\end_inset + +. +\end_layout + \begin_layout Standard By using \emph on @@ -4381,6 +4492,135 @@ unzip the files in the appropriate places. \end_layout +\begin_layout Subsubsection +Set up ccache (optional) +\end_layout + +\begin_layout Standard +If you have +\begin_inset Flex Software +status open + +\begin_layout Plain Layout +ccache +\end_layout + +\end_inset + + installed, you will need to set it up so that it works with precompiled + headers. + To do this, run the following command. +\begin_inset listings +lstparams "language=bash" +inline false +status open + +\begin_layout Plain Layout + +ccache --set-config=sloppiness=pch_defines,time_macros +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Alternatively, if you are using +\begin_inset Flex Software +status open + +\begin_layout Plain Layout +bash +\end_layout + +\end_inset + + as your shell and +\begin_inset Flex Software +status open + +\begin_layout Plain Layout +ccache +\end_layout + +\end_inset + + is installed in +\begin_inset Flex File +status open + +\begin_layout Plain Layout +binary_c +\end_layout + +\end_inset + + (the standard location in +\begin_inset Flex OS +status open + +\begin_layout Plain Layout +Ubuntu Linux +\end_layout + +\end_inset + +, put the following in your +\begin_inset Flex File +status open + +\begin_layout Plain Layout +.bashrc +\end_layout + +\end_inset + + to have +\begin_inset Flex Software +status open + +\begin_layout Plain Layout +ccache +\end_layout + +\end_inset + + always behave as you wish. +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +# use ccache if available +\end_layout + +\begin_layout Plain Layout + +if [[ -d /usr/lib/ccache ]]; then +\end_layout + +\begin_layout Plain Layout + + export PATH=/usr/lib/ccache/:$PATH +\end_layout + +\begin_layout Plain Layout + + export CCACHE_SLOPPINESS=pch_defines,time_macros +\end_layout + +\begin_layout Plain Layout + +fi +\end_layout + +\end_inset + + +\end_layout + \begin_layout Subsubsection Building with Meson \begin_inset CommandInset label @@ -6000,24 +6240,21 @@ tbse \end_inset pgo Profile guided optimization. - This builds -\emph on + This option is deprecated. + Please use the +\begin_inset Flex File +status open + +\begin_layout Plain Layout +meson/pgo.sh +\end_layout -\begin_inset Formula $\binaryc$ \end_inset + script instead (see +\begin_inset space ~ +\end_inset -\emph default - once, runs a number of systems, then rebuilds with extra optimization based - on the profile generated by the runs. - This works for -\emph on -GCC -\emph default - and probably also -\emph on -clang -\emph default . \end_layout @@ -19081,70 +19318,64 @@ tbse <filename> \end_layout \begin_layout Subsection -How to use profile guided optimization (PGO) +How to use profile-guided optimization (PGO) \end_layout \begin_layout Standard -When compiling with -\begin_inset Flex Software -status open - -\begin_layout Plain Layout -gcc -\end_layout - -\end_inset +\begin_inset CommandInset label +LatexCommand label +name "subsec:How-to-use-PGO" -, just run -\begin_inset Newline newline \end_inset -\family typewriter -\series bold - -\begin_inset listings -lstparams "language=bash" -inline false +\begin_inset Flex Software status open \begin_layout Plain Layout - -tbse pgo +Meson \end_layout \end_inset - -\end_layout - -\begin_layout Standard -You may want to change the -\begin_inset Flex Args + supports profile-guided optimization (PGO), and this has been written into + the +\begin_inset Flex File status open \begin_layout Plain Layout -REPEAT +meson/pgo.sh \end_layout \end_inset - variable as defined in -\begin_inset Flex bashscript + script which you can use to test it. + You should just run this, with an optional argument that is the number + of test systems (this defaults to 1000), e.g. +\begin_inset space ~ +\end_inset + +from the +\begin_inset Formula $\binaryc$ +\end_inset + + root directory: +\begin_inset listings +inline false status open \begin_layout Plain Layout -tbse + +./meson/pgo.sh 1000 \end_layout \end_inset -. - It is set to 10000, but if your code is running too slowly, set it to less. + \end_layout \begin_layout Standard -For details see +For details about profile-guided optimization, please see \begin_inset Flex URL status open @@ -19155,11 +19386,7 @@ https://en.wikipedia.org/wiki/Profile-guided_optimization \end_inset - -\end_layout - -\begin_layout Standard -Generally, I find a 5-10% speedup from PGO. + or your compiler's documentation. \end_layout \begin_layout Subsection diff --git a/meson.build b/meson.build index 240f6edc428e19285c7983e43a5174ef0b3875c5..acb9198eeb0c23b9a39700fc67a5ea3f3c1fe09f 100644 --- a/meson.build +++ b/meson.build @@ -10,7 +10,6 @@ ############################################################ # TODO: # -# automate symlink of libbinary_c.so? # 'gprof'/'gcov' builds # profile-guided optimization # build data_objects in builddir, not in source tree @@ -19,6 +18,12 @@ # ############################################################ # +# See also +# https://github.com/mesonbuild/meson/blob/master/docs/markdown/howtox.md +# as a useful cookbook. +# +############################################################ +# # A typical clean build with gcc and "time make" gives # 95.23user 21.08system 0:34.64elapsed 335%CPU (0avgtext+0avgdata 425420maxresident)k # @@ -28,12 +33,13 @@ ############################################################ # define the binary_c project project( - 'binary_c','c', - version : run_command('sh','-c','meson/binary_c_version.sh').stdout().strip(), - default_options : [ - 'c_std=gnu99', - ] - ) + 'binary_c','c', + version : run_command('sh','-c','meson/binary_c_version.sh').stdout().strip(), + default_options : [ + 'c_std=gnu99', + ] +) +binary_c_version = run_command('sh','-c','meson/binary_c_version.sh').stdout().strip() compiler = meson.get_compiler('c') ############################################################ @@ -58,34 +64,27 @@ git_url = run_command('sh','-c','meson/git_url.sh').stdout().strip() svn_url = run_command('sh','-c','meson/svn_url.sh').stdout().strip() ############################################################ -# default include directories +# default include and library search directories incdirs = [ '.', './src' ] libdirs = [ './src' ] absolute_incdirs = [ binary_c, binary_c_src ] absolute_libdirs = [ ] -############################################################ -# list of libraries with which we should link: libs come -# first and are appended to, postlibs come last. -libs = ['-lc','-lm'] -postlibs = ['-lc','-lm','-ldl'] - ############################################################ # determine whether we're a debug or generic build have_gnu99 = compiler.has_argument('-std=gnu99') have_avx = compiler.has_argument('-mavx') ############################################################ -# default C flags (compiler options) - -# TODO: do not omit frame pointer if profile guided -cflags = ['-fPIC','-DALIGNSIZE=16'] +# default C flags +# +cflags = ['-DALIGNSIZE=16'] if have_gnu99 - cflags += [ '-std=gnu99' ] + cflags += [ '-std=gnu99' ] endif if have_avx and get_option('generic') == false - cflags += [ '-mavx' ] + cflags += [ '-mavx' ] endif ############################################################ @@ -95,45 +94,48 @@ optional_flags = [ ] # generic build if get_option('generic') == true - optional_flags += [ - '-mtune=generic', - ] + optional_flags += [ + '-mtune=generic', + ] else - optional_flags += [ - '-march=native', - '-mtune=native', - ] + optional_flags += [ + '-march=native', + '-mtune=native', + ] endif # accurate mathematical options if get_option('accurate') == true - optional_flags += [ - '-frounding-math', - '-fno-stack-protector', - '-ffloat-store', - '-fno-fast-math' - ] + optional_flags += [ + '-frounding-math', + '-fno-stack-protector', + '-ffloat-store', + '-fno-fast-math' + ] else - optional_flags += [ - '-ffast-math', - '-fno-associative-math', - ] + optional_flags += [ + '-ffast-math', + '-fno-associative-math', + ] endif optional_flags += [ - '-fno-finite-math-only', - '-fsignaling-nans', - '-fomit-frame-pointer', - '-fvisibility=hidden', - ] - + '-fno-finite-math-only', + '-fsignaling-nans', + '-fomit-frame-pointer', + '-fvisibility=hidden', +] + ############################################################ # debug C flags if get_option('buildtype').startswith('debug') - optional_flags += [ '-rdynamic', '-O0' ] + optional_flags += [ '-rdynamic', '-O0' ] endif -# flags that are not strictly required, but that help a lot +############################################################ +# Now go through the optional_flags, and use those that +# are supported by the compiler. +# foreach _flag : optional_flags if compiler.has_argument(_flag) cflags += _flag @@ -145,195 +147,221 @@ endforeach # per-compiler options if compiler.get_id() == 'clang' - # clang flags - cflags += [ '-fbracket-depth=512' ] + # clang flags + cflags += [ '-fbracket-depth=512' ] else - # default to gcc flags - cflags += [] + # default to gcc flags + cflags += [] endif -libs += [] - ############################################################ # system options cflags += '-DCPUFREQ=' + cpufreq if host_machine.system() == 'linux' - # Linux system - cflags += ['-DLINUX', '-DLARGEFILE_SOURCE'] - - # check for perf_event_paranoid - _perf_event = run_command('cat','/proc/sys/kernel/perf_event_paranoid').stdout().strip() - if _perf_event == '1' or _perf_event == '2' - cflags += '-D__HAVE_PERF_EVENTS__' - endif + # Linux system + cflags += ['-DLINUX', '-DLARGEFILE_SOURCE'] endif if compiler.compiles('int main(int argc,char **argv){return 0;}', args : '-m64', name : '64-bit check') - # 64-bit system - cflags += '-D_FILE_OFFSET_BITS=64' + # 64-bit system + cflags += '-D_FILE_OFFSET_BITS=64' else - # assume 32-bit system + # assume 32-bit system endif ############################################################ # version control options if git_revision != '' - _flag = '-DGIT_REVISION="' + git_revision + '"' - cflags += _flag + _flag = '-DGIT_REVISION="' + git_revision + '"' + cflags += _flag endif if svn_revision != '' - _flag = '-DSVN_REVISION="' + svn_revision + '"' - cflags += _flag + _flag = '-DSVN_REVISION="' + svn_revision + '"' + cflags += _flag endif if git_url != '' - _flag = '-DGIT_URL="' + git_url + '"' - cflags += _flag + _flag = '-DGIT_URL="' + git_url + '"' + cflags += _flag endif if svn_url != '' - _flag = '-DSVN_URL="' + svn_url + '"' - cflags += _flag + _flag = '-DSVN_URL="' + svn_url + '"' + cflags += _flag endif ############################################################ -# dependencies that have pkg-config -libgsl_dep = compiler.find_library('gsl',required: true) - +# dependencies are put in the list called dependencies +# +dependencies = [ ] ############################################################ # dependencies that usually have no pkg-config # THESE NEED TO BE SET IN $LIBRARY_PATH (or $LIBPATH on Windoze) # -# required system libraries -libc_dep = compiler.find_library('c', required: true) -libm_dep = compiler.find_library('m', required: true) - -############################################################ -# dependencies -# - -####### -# GSL # -# -# todo : https://mesonbuild.com/Reference-tables.html see "Dependency lookup methods" -if libgsl_dep.found() - cflags += run_command('sh','-c','gsl-config --cflags').stdout().strip().split(' ') - cflags += '-DUSE_GSL' - libs += run_command('sh','-c','gsl-config --libs').stdout().strip().split(' ') - gsl_libdirs = run_command('sh','-c','gsl-config --libs | tr " " "\n"|grep ^-L | tr "\n" " "').stdout().strip().split(' ') - libdirs += gsl_libdirs - incdirs += run_command('sh','-c','gsl-config --prefix').stdout().strip()+'/include' -endif - - -############################# -# required libraries # -# libgsl etc. # -# -foreach libname : ['gsl'] - _dep = compiler.find_library(libname,required:false) +# system libraries : note that libm may not be required +# on some systems (GSL may also specify) +dependencies += [ + compiler.find_library('c', required: true), + compiler.find_library('m', required: false), +] + + +############################################################ +# libraries : required and optional +# +_required_libraries = [ + 'c', + 'gsl', + 'gslcblas', +] +_optional_libraries = [ + 'backtrace', + 'bfd', + 'bsd', + 'iberty', + 'm', # optional on some platforms (gsl probably required is) + 'memoize', + 'rinterpolate', +] +libs = [] # list sent to the compiler +foreach libname : _required_libraries + _dep = compiler.find_library(libname, + required:true) if _dep.found() - cflags += '-D__HAVE_LIB' + libname.to_upper() +'__' - libs += '-l' + libname + cflags += '-D__HAVE_LIB' + libname.to_upper() +'__' + libs += '-l' + libname + + # extras + if libname == 'gsl' + # use gsl-config to find cflags, libraries, etc. + message('Adding GSL-specific flags from gsl-config') + cflags += run_command('sh','-c','gsl-config --cflags').stdout().strip().split(' ') + cflags += '-DUSE_GSL' + libs += run_command('sh','-c','gsl-config --libs').stdout().strip().split(' ') + gsl_libdirs = run_command('sh','-c','gsl-config --libs | tr " " "\n"|grep ^-L | tr "\n" " "').stdout().strip().split(' ') + libdirs += gsl_libdirs + incdirs += run_command('sh','-c','gsl-config --prefix').stdout().strip()+'/include' + endif endif + dependencies += _dep endforeach +# Note : this should work, but does not :( +# +#gsl_dep = dependency( +# 'gsl', +# required : true, +# version : '>=2.4', +# method : 'config-tool', +# ) + ############################# -# optional libraries # -# libbacktrace, libbfd etc. # +# optional libraries +# libbacktrace, libbfd etc. +# (generic builds should not use these) # if get_option('generic') == false - foreach libname : ['bfd','backtrace','bsd','iberty','memoize','rinterpolate'] - _dep = compiler.find_library(libname,required:false) - if _dep.found() - cflags += '-D__HAVE_LIB' + libname.to_upper() +'__' - libs += '-l' + libname - endif - endforeach + foreach libname : _optional_libraries + _dep = compiler.find_library(libname,required:false) + if _dep.found() + cflags += '-D__HAVE_LIB' + libname.to_upper() +'__' + libs += '-l' + libname + endif + endforeach endif + +############################################################ +# features which are converted into preprocessor flags (-D) +# + ########### # drand48 # # if compiler.sizeof('drand48_r', prefix : '#include <stdlib.h>') > 0 - cflags += '-D__HAVE_DRAND48__' + cflags += '-D__HAVE_DRAND48__' endif - + ############ # malloc.h # # if compiler.has_header('malloc.h') - cflags += '-D__HAVE_MALLOC_H__' + cflags += '-D__HAVE_MALLOC_H__' endif ################################# # pkg-config (external command) # # if run_command('pkg-config','--version').returncode() == 0 - cflags += '-D__HAVE_PKG_CONFIG__' + cflags += '-D__HAVE_PKG_CONFIG__' endif ########################### # valgrind (header files) # # if compiler.has_header('valgrind/valgrind.h') - cflags += '-D__HAVE_VALGRIND__' + cflags += '-D__HAVE_VALGRIND__' endif ################### # show_starstruct # # if run_command('sh','-c','meson/make_starstruct.sh').returncode() == 0 - cflags += '-D__SHOW_STARDATA__' + cflags += '-D__SHOW_STARDATA__' endif ################### # diff_starstruct # # if run_command('sh','-c','meson/diff_starstruct.sh').returncode() == 0 - cflags += '-D__DIFF_STARDATA__' + cflags += '-D__DIFF_STARDATA__' endif ######################## # Unsupported features # # if compiler.get_id() != 'gcc' and compiler.get_id() != 'clang' - cflags += '-UBACKTRACE' + cflags += '-UBACKTRACE' endif ############################################################ # make a list of include directories +# We do this so that $HOME/include is searched (e.g. for +# libgsl) +# my_incdirs = [] found = false -foreach idir : [ - homedir + '/include', - '/usr/include', - '/usr/local/include', - ] - inc_arg = idir - _Inc_arg = '-I' + idir - if not found and compiler.has_header('gsl/gsl_blas.h', - args: _Inc_arg) - my_incdirs += [inc_arg] - found = true - endif +_include_search_paths = [ + homedir + '/include', + '/usr/include', + '/usr/local/include', +] +foreach idir : _include_search_paths + inc_arg = idir + _Inc_arg = '-I' + idir + if not found and compiler.has_header('gsl/gsl_blas.h', + args: _Inc_arg) + my_incdirs += [inc_arg] + found = true + endif endforeach -incdirs += [my_incdirs] +incdirs += [ my_incdirs ] ############################################################ # data objects # # list and build them +message('Checking and building data objects') data_objects = run_command('meson/data_object_list_and_build.sh').stdout().strip().split(' ') if get_option('clean_data_objects') == true - run_command('meson/clean_data_objects.sh') + run_command('meson/clean_data_objects.sh') endif ############################################################ @@ -345,17 +373,12 @@ run_command('meson/make_version_macros.pl') # source files # c_sourcefiles = run_command('meson/c_sourcefiles.sh').stdout().strip().split('\n') +c_main_sourcefiles = run_command('meson/c_main_sourcefiles.sh').stdout().strip().split('\n') h_sourcefiles = run_command('meson/h_sourcefiles.sh').stdout().strip().split('\n') -############################################################ -# full list of libraries with which we wish to link -# -libs = libs + postlibs - ############################################################ # extra quoted flags to pass into binary_c # - cflags_with_O = cflags + [ '-O' + get_option('optimization') ] # cflags with -O<n> cflags_quoted = ' '.join(cflags_with_O) # turn to string cflags_quoted = ''.join(cflags_quoted.split('"')) # remove " @@ -370,19 +393,25 @@ libs_quoted = '-DLIBS=' + ''.join(['"', ' '.join(libs),'"']) libs_quoted = '_slash_'.join(libs_quoted.split('/')) # hence a quoted version of the cflags -quoted_cflags_list = [ cflags_quoted, - cc_quoted, - incdirs_quoted, - ld_quoted, - libdirs_quoted, - libs_quoted, - ] +quoted_cflags_list = [ + cflags_quoted, + cc_quoted, + incdirs_quoted, + ld_quoted, + libdirs_quoted, + libs_quoted, +] ############################################################ # compiler warning flags ############################################################ warn_flags = [] -foreach _arg : ['all','format','strict-prototypes','format-signedness'] +foreach _arg : [ + 'all', + 'format', + 'strict-prototypes', + 'format-signedness' +] _warn_arg = '-W' + _arg if compiler.has_argument(_warn_arg) warn_flags += _warn_arg @@ -401,90 +430,137 @@ cflags += warn_flags # its dependencies in a pch.d/gch.d file. This is a bit # complicated, as you will see below. # - -if get_option('usepch') == true - - _opt = '-O' + get_option('optimization') # required for __OPTIMIZE__ - - # normal dep file - _depfile_path = binary_c_src + '/binary_c.h.gch.d' - - # make a list of incdirs each prefixed by -I - _incdirs = [] - foreach _i : absolute_incdirs - _I = '-I' + _i - _incdirs += _I - endforeach - _incdirs += [ '-I.' ] - - # choose your compiler... - if compiler.get_id() == 'clang' - # clang PCH - - _pch = 'binary_c.h.pch' - use_pch_cflags = [ '-include-pch', _pch ] - pch_cflags = [ - _opt, - _incdirs, - ] - pch_sourcefiles = [ _pch ] - pch_post = [ '-o', _pch ] - pch_depfile = '' - - else - # GCC PCH - - _gch = 'binary_c.h.gch' - _gchd = '../src/' + _gch + '.d' - use_pch_cflags = [ ] # -include is not required - pch_cflags = [ _opt, - _incdirs, - '-MT', 'binary_c.h.gch', - '-MMD', - '-MP', - '-MF', _depfile_path, - '-x', 'c-header' - ] - pch_sourcefiles = [ _gch ] - cflags += [ '-fpch-deps', '-fpch-preprocess' ] - pch_post = [ ] - pch_depfile = _gch + '.d' - endif - - - # make cflags for pch build - pch_cflags_array = cflags + pch_cflags - - # append usage flags - cflags += use_pch_cflags - - pch_compiler = compiler.cmd_array() + pch_cflags_array - - precompiled_headers = custom_target( - 'binary_c.h.pch', - build_by_default : true, - input : ['src/binary_c.h'], - output : pch_sourcefiles, - command : [ pch_compiler, '-gdwarf-2', '@INPUT@', pch_post ], - depend_files : [h_sourcefiles], - ) +if get_option('usepch') == true + # get optimization level, required for __OPTIMIZE__ + _opt = '-O' + get_option('optimization') + + # make sure we precompile with fPIC and symbols + _pic = ['-g','-fPIC'] + + # normal dep file + _depfile_path = binary_c_src + '/binary_c.h.gch.d' + + # make a list of incdirs each prefixed by -I + _incdirs = [] + foreach _i : absolute_incdirs + _I = '-I' + _i + _incdirs += _I + endforeach + _incdirs += [ '-I.' ] + + # choose your compiler... + if compiler.get_id() == 'clang' + # clang PCH + + _pch = 'binary_c.h.pch' + use_pch_cflags = [ + '-include-pch', + _pch ] + pch_cflags = [ + _opt, + _pic, + _incdirs, + ] + pch_sourcefiles = [ _pch ] + pch_post = [ '-o', _pch ] + pch_depfile = '' + + else + # GCC PCH + + _gch = 'binary_c.h.gch' + _gchd = '../src/' + _gch + '.d' + use_pch_cflags = [ ] # -include is not required + pch_cflags = [ + _opt, + _pic, + _incdirs, + '-MT', 'binary_c.h.gch', + '-MMD', + '-MP', + '-MF', _depfile_path, + '-x', 'c-header' + ] + pch_sourcefiles = [ _gch ] + cflags += [ + '-fpch-deps', + '-fpch-preprocess' + ] + pch_post = [ ] + pch_depfile = _gch + '.d' + endif + + # make cflags for pch build + pch_cflags_array = cflags + pch_cflags + + # append usage flags + cflags += use_pch_cflags + + # make PCH compiler: this is just the normal compiler with PCH flags + pch_compiler = compiler.cmd_array() + pch_cflags_array + + message('building precompiled headers') + precompiled_headers = custom_target( + 'binary_c.h.pch', + build_by_default : true, + input : ['src/binary_c.h'], + output : pch_sourcefiles, + command : [ + pch_compiler, + '-gdwarf-2', + '@INPUT@', + pch_post + ], + depend_files : [ h_sourcefiles ], + ) else - # disable PCH by removing the files it would have generated - - all_pch_sourcefiles = [ 'binary_c.h.gch', 'binary_c.h.pch' ] - precompiled_headers = custom_target( - 'binary_c.h.pch', - build_by_default : true, - input : ['src/binary_c.h'], - output : all_pch_sourcefiles, - command : [ 'rm', '-f', all_pch_sourcefiles ], - depend_files : [h_sourcefiles], - ) + # disable PCH by removing the files it would have generated + + all_pch_sourcefiles = [ 'binary_c.h.gch', 'binary_c.h.pch' ] + precompiled_headers = custom_target( + 'binary_c.h.pch', + build_by_default : true, + input : [ 'src/binary_c.h' ], + output : all_pch_sourcefiles, + command : [ 'rm', '-f', all_pch_sourcefiles ], + depend_files : [h_sourcefiles], + ) endif +############################################################ +# command to install binary_c in its 'legacy' locations +# (required for binary_grid2) +binary_c_legacy_install_cmd = [ + 'cp','--remove-destination','binary_c','../', + '&&', + 'cp','--remove-destination','libbinary_c.so','../src/', + '&&', + 'echo','libbinary_c.so built with symbols:', + '&&', + '../meson/list_shared_symbols.sh','libbinary_c.so' +] + +############################################################ +# +# Convenience for Rob: try to locate binary_grid2.pm and +# hence touch (and rebuild) it when the shared library is +# rebuild +# +if run_command('sh','-c','meson/check_binary_grid2.sh').returncode() == 0 + binary_grid2_file = run_command( + 'sh', + '-c', + 'meson/check_binary_grid2.sh' + ).stdout().strip() + binary_c_legacy_install_cmd += [ + '&&', + 'touch', + binary_grid2_file + ] +endif ############################################################ # @@ -492,30 +568,72 @@ endif # run: ninja libbinary_c_symlink # libbinary_c_symlink = custom_target( - 'libbinary_c_symlink', - build_by_default: false, - output: [ 'libbinary_c_symlink' ], - command: [ 'sh', '-c', '../meson/symlink_libbinary_c.sh' ], - ) - + 'libbinary_c_symlink', + build_by_default: false, + output: [ 'libbinary_c_symlink' ], + command: [ + 'sh', + '-c', + '../meson/symlink_libbinary_c.sh' + ], +) + + +############################################################ +# +# make binary_c objects +# +# We put the objects in here so they can be shared by +# the executable and library builds. We're not really +# interested in the static library, but we have to call +# this build something. +# +binary_c_objects = build_target( + 'binary_c_objects', + build_by_default: true, + pic: true, + target_type : 'static_library', # pretend we're a static library! + sources : [ + c_sourcefiles, + h_sourcefiles, + precompiled_headers + ], + include_directories: include_directories(incdirs), + dependencies : dependencies, + c_args : [ + cflags, + quoted_cflags_list, + ], + objects : data_objects, + link_args : [ + libs, + ], + ) + ############################################################ # # make shared library # run: ninja libbinary_c.so # binary_c_shared_library = shared_library( - get_option('libname'), - build_by_default : false, - install: true, - sources : [c_sourcefiles, h_sourcefiles, precompiled_headers ], - include_directories: include_directories(incdirs), - dependencies : [ libgsl_dep ], - c_args : [ cflags, quoted_cflags_list, '-fvisibility=hidden' ], - link_args : libs, - objects : data_objects, - ) - - + get_option('libname'), + build_by_default : false, + install: true, + include_directories: include_directories(incdirs), + dependencies : [ dependencies ], + c_args : [ + cflags, + quoted_cflags_list, + '--whole-archive', + ], + link_whole: [ + binary_c_objects, + ], + link_args : [ + libs, + '-fvisibility=hidden', + ], +) ############################################################ # @@ -523,48 +641,37 @@ binary_c_shared_library = shared_library( # run: ninja binary_c # binary_c_executable = executable( - 'binary_c', - install: true, - sources : [ - c_sourcefiles, - h_sourcefiles, - precompiled_headers - ], - include_directories: include_directories(incdirs), - dependencies : [ libgsl_dep ], - c_args : [ - cflags, - quoted_cflags_list - ], - link_args : libs, - objects : data_objects, - ) - - -############################################################ -# -# symlink executable to binary_c directory -# run : ninja binary_c_symlink -# -binary_c_symlink = custom_target('symlink_binary_c', - build_by_default: true, - output: ['binary_c_symlink'], - command: [ 'sh', '-c', '../meson/symlink_binary_c.sh' ], - depends : [ binary_c_executable ], - ) - + 'binary_c', + build_by_default : true, + install: true, + sources : [ + c_main_sourcefiles, + ], + include_directories: include_directories(incdirs), + dependencies : [ dependencies ], + c_args : [ + cflags, + quoted_cflags_list, + ], + objects : data_objects, + link_args : [ + libs, + ], + link_with: [ binary_c_objects ], +) ############################################################ # install both binary_c and libbinary_c.so in their legacy # locations -binary_c_install_legacy = custom_target('binary_c_install_legacy', - build_by_default: false, - output: ['binary_c_install_legacy'], - command: [ - 'cp','--remove-destination','binary_c','../', - '&&', - 'cp','--remove-destination','libbinary_c.so','../src/' - ], - depends : [ binary_c_executable, binary_c_shared_library ], - ) +# +binary_c_install_legacy = custom_target( + 'binary_c_install_legacy', + build_by_default: false, + output: [ 'binary_c_install_legacy' ], + command: binary_c_legacy_install_cmd, + depends : [ + binary_c_executable, + binary_c_shared_library, + ], +) diff --git a/meson/c_main_sourcefiles.sh b/meson/c_main_sourcefiles.sh new file mode 100755 index 0000000000000000000000000000000000000000..395085b7075535419111244adc32bb8abf0f52f2 --- /dev/null +++ b/meson/c_main_sourcefiles.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# list binary_c C source files for meson +ls -1 src/*.c src/*/*.c |grep main.c diff --git a/meson/check_binary_grid2.sh b/meson/check_binary_grid2.sh new file mode 100755 index 0000000000000000000000000000000000000000..fb0c695f29d28e6cc6535744ce6fca9a594e7ee4 --- /dev/null +++ b/meson/check_binary_grid2.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +# test if Rob's binary_grid2.pm exists +# +# if so, echo its path and return 0 +# +# otherwise, return 1 +FILE="$HOME/progs/perl/modules/astro/binary_grid/lib/binary_grid2.pm" +if [ -f $FILE ]; then + echo $FILE + exit 0 +else + exit 1 +fi + diff --git a/meson/list_shared_symbols.sh b/meson/list_shared_symbols.sh new file mode 100755 index 0000000000000000000000000000000000000000..b9c524948b7d8c3bc4017269f2a2019710be8e66 --- /dev/null +++ b/meson/list_shared_symbols.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# list shared symbols in the library (file name passed in) +SOFILE=$1 + +# red +echo -e "\e[31m" + +nm -CD -f p $SOFILE | awk '{if ($2 == "T"){print $1}}' | grep -v _fini|grep -v _init | tr "\n" " " + +#reset +echo -e "\e[0m" + diff --git a/meson/pgo.sh b/meson/pgo.sh new file mode 100755 index 0000000000000000000000000000000000000000..50b9960d447c0139262d239f86b1d390d15e4490 --- /dev/null +++ b/meson/pgo.sh @@ -0,0 +1,114 @@ +#!/bin/bash + +# script to do PGO with Meson + + +# set defaults +BUILDDIR="builddir" +N=$1 +: ${N:="1000"} +NCORES=`cat /proc/cpuinfo |grep -i Processor | wc -l` +: ${NCORES:="1"} +TMP="/tmp/" +NCORES1=$((NCORES - 1)) +REPEAT_PER_CORE=$(($N/$NCORES)) +SLEEP=0 +MESON=meson +NINJA=ninja + +# where to redirect stderr, stdout on meson and ninja calls +MESON_STDERR=/dev/stderr +MESON_STDOUT=/dev/null +NINJA_STDERR=/dev/stderr +NINJA_STDOUT=/dev/null + +# tbse command +TBSE="./tbse" +WARMUP_SECS=0 +COMMAND1="random_systems 1 repeat $REPEAT_PER_CORE warmup_cpu $WARMUP_SECS" + +# status message +echo "Using Meson to build binary_c with Profile Guided Optimization (PGO) on $N systems across $NCORES cores" + +# function to kill child processes +KillChildren() { + local pid="${1}" + local self="${2:-false}" + if children="$(pgrep -P "$pid")"; then + for child in $children; do + KillChildren "$child" true + done + fi + + if [ "$self" == true ]; then + #kill -s SIGTERM "$pid" || (sleep 10 && kill -9 "$pid" &) + kill -9 "$pid" + fi +} + +# kill children on exit +trap '[ -n "$(jobs -pr)" ] && KillChildren $$' INT QUIT TERM EXIT + +############################################################ +# first build: use builddir if already avaialble +echo "Configure meson for PGO build 1" +if [ -d $BUILDDIR ] ; then + meson configure $BUILDDIR -Db_pgo=generate > $MESON_STDOUT 2> $MESON_STDERR +else + meson $BUILDDIR -Db_pgo=generate > $MESON_STDOUT 2> $MESON_STDERR +fi +echo "Build (1) with ninja" +#ninja -C $BUILDDIR > $NINJA_STDOUT 2> $NINJA_STDERR + + + +############################################################ +# run and filter to files +START=`date +%s%N` +echo "Running binary_c" +for i in `seq 0 $NCORES1`; do + echo "Launch tbse on core $i" + taskset -c $i $TBSE $COMMAND1 | grep At | awk '{print substr($0, index($0,$5))}' > /tmp/binary_c_pgo.$i & + sleep $SLEEP +done +wait +END=`date +%s%N` +PGO1_DURATION=$(echo "(0.000000001*($END - $START))"|bc) + +############################################################ +# rebuild +echo "Configure meson for PGO build 2" +meson configure $BUILDDIR -Db_pgo=use > $MESON_STDOUT 2> $MESON_STDERR +echo "Build (2) with ninja" +ninja -C $BUILDDIR > $NINJA_STDOUT 2> $NINJA_STDERR + +# remove trap +trap - INT QUIT TERM EXIT + +############################################################ +# rerun + +# kill children on exit +trap '[ -n "$(jobs -pr)" ] && KillChildren $$' INT QUIT TERM EXIT + +START=`date +%s%N` +echo "Running binary_c" +for i in `seq 0 $NCORES1`; do + env FIRST_TBSE="warmup_cpu $WARMUP_SECS" taskset -c $i $TBSE /tmp/binary_c_pgo.$i 2>&1 >/dev/null & + sleep $SLEEP +done +wait +END=`date +%s%N` +PGO2_DURATION=$(echo "(0.000000001*($END - $START))"|bc) + +# remove trap +trap - INT QUIT TERM EXIT + +echo "Run 1 (without PGO) took : $PGO1_DURATION s" +echo "Run 2 ( with PGO) took : $PGO2_DURATION s" + +# final speedup % +echo -n "Profile guided optimization speedup is " +echo -n $(echo "(100.0*($PGO1_DURATION-$PGO2_DURATION)/$PGO1_DURATION)"|bc) +echo "%" +exit diff --git a/src/perl/scripts2/template.pl b/src/perl/scripts2/template.pl index 5a24038f53e834749cc8dc8beaf0345e70adfa9f..e457dc4df3b01e4ec024fc2caf230f12cf9d901e 100755 --- a/src/perl/scripts2/template.pl +++ b/src/perl/scripts2/template.pl @@ -102,7 +102,12 @@ $population->set( # stardata->star[0].mass, # stardata->model.probability, # stardata->model.dt); -# ' + # ' + + + flexigrid => { + 'grid type' => 'monte carlo' + } ); ############################################################ @@ -135,6 +140,7 @@ if($duplicity == 0) 'precode' =>'$m1=exp($lnm1);', 'probdist' =>'Kroupa2001($m1)*$m1', 'dphasevol' =>'$dlnm1', + 'gridtype' =>'monte carlo', ); } elsif($duplicity == 1) diff --git a/src/setup/version.c b/src/setup/version.c index 6d2195f0371a8c155b8b9e8fa76625498fcdaa91..e28a53fb93b7dc10fcc2b84e75bd7e7d97a457f8 100644 --- a/src/setup/version.c +++ b/src/setup/version.c @@ -760,7 +760,6 @@ void version(struct stardata_t * RESTRICT const stardata) Macrotest(__APPLE__); Macrotest(__arm__); Macrotest(__i386__); - Macrotest(__HAVE_PERF_EVENTS__); #ifdef ALIGNSIZE Printf("Memory is aligned to %d bytes (set in ALIGNSIZE)\n",ALIGNSIZE); #else diff --git a/tbse b/tbse index f1ec1c1070e9d93a698d0b323f21f434788c88c1..8866bff0f01de9b946acb30ad541ea73c496b1bb 100755 --- a/tbse +++ b/tbse @@ -2366,7 +2366,7 @@ then ARGS=$(echo $ARGS | sed -e s/At\ 20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]\ [0-9][0-9]\:[0-9][0-9]\:[0-9][0-9]\ \:\ //) # run binary_c - $ARGS_PREFIX $DEFAULT_ARGS $ARGS $ARGS_POSTFIX $@ + $ARGS_PREFIX $DEFAULT_ARGS $ARGS $ARGS_POSTFIX $@ $FIRST_TBSE ERROR=$? # save return code and exit if non-zero if (($ERROR != 0)); then @@ -2376,6 +2376,10 @@ then echo exit $ERROR fi + + if [[ ! -z $FIRST_TBSE ]]; then + FIRST_TBSE="" + fi fi done < <(grep -v \# $argfile ) done @@ -2409,6 +2413,15 @@ fi if [ "$RUNMODE" == "pgo" ]; then + echo "Profile-guided optimization (PGO) through tbse has been deprecated : please use Meson to do pgo. A bash script to do this (meson/pgo.sh), run with as + +./meson/pgo.sh <N> + +where N is the number of systems to run, per CPU core, in a timing test. + +" + exit + # profile-guided optimisation build: this option # configures, builds, runs, rebuilds and reruns bonnfires # so that it uses profile-guided optimisation, i.e.