diff --git a/hermit/tools/Makefile b/hermit/tools/Makefile index 01f2288f9..63980ae0b 100644 --- a/hermit/tools/Makefile +++ b/hermit/tools/Makefile @@ -5,7 +5,7 @@ CC = gcc CFLAGS = -O2 -Wall HEXDUMP = hexdump LDFLGAS = -PROXYFILES = $(shell find ../usr/tests -name '*.bin') $(shell find ../usr/benchmarks -name '*.bin') +PROXYFILES = $(shell find ../usr/tests -name '*.bin') $(shell find ../usr/benchmarks -name '*.bin') $(shell find ../usr/openmpbench -name '*.bin') # Prettify output V = 0 diff --git a/hermit/usr/Makefile b/hermit/usr/Makefile index 3241de5aa..a0c2ec1c3 100644 --- a/hermit/usr/Makefile +++ b/hermit/usr/Makefile @@ -28,6 +28,8 @@ demo: $Q$(MAKE) CC_FOR_TARGET=$(CC_FOR_TARGET) CXX_FOR_TARGET=$(CXX_FOR_TARGET) CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" LDFLAGS_FOR_TARGET="$(LDFLAGS_FOR_TARGET)" OBJCOPY_FOR_TARGET=$(OBJCOPY_FOR_TARGET) -C tests $Q$(MAKE) CC_FOR_TARGET=$(CC_FOR_TARGET) CXX_FOR_TARGET=$(CXX_FOR_TARGET) CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" LDFLAGS_FOR_TARGET="$(LDFLAGS_FOR_TARGET)" OBJCOPY_FOR_TARGET=$(OBJCOPY_FOR_TARGET) -C benchmarks depend $Q$(MAKE) CC_FOR_TARGET=$(CC_FOR_TARGET) CXX_FOR_TARGET=$(CXX_FOR_TARGET) CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" LDFLAGS_FOR_TARGET="$(LDFLAGS_FOR_TARGET)" OBJCOPY_FOR_TARGET=$(OBJCOPY_FOR_TARGET) -C benchmarks + #$Q$(MAKE) CC_FOR_TARGET=$(CC_FOR_TARGET) CXX_FOR_TARGET=$(CXX_FOR_TARGET) CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" LDFLAGS_FOR_TARGET="$(LDFLAGS_FOR_TARGET)" OBJCOPY_FOR_TARGET=$(OBJCOPY_FOR_TARGET) -C openmpbench depend + $Q$(MAKE) CC_FOR_TARGET=$(CC_FOR_TARGET) CXX_FOR_TARGET=$(CXX_FOR_TARGET) CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" LDFLAGS_FOR_TARGET="$(LDFLAGS_FOR_TARGET)" OBJCOPY_FOR_TARGET=$(OBJCOPY_FOR_TARGET) -C openmpbench $(ARCH): $Q$(MKDIR) $(TMP) @@ -81,6 +83,7 @@ clean: @echo Cleaning toolchain $Q$(MAKE) -C tests clean $Q$(MAKE) -C benchmarks clean + $Q$(MAKE) -C openmpbench clean veryclean: @echo Propper cleaning of the toolchain @@ -89,6 +92,7 @@ veryclean: $Q$(MAKE) -C ircce veryclean $Q$(MAKE) -C tests veryclean $Q$(MAKE) -C benchmarks veryclean + $Q$(MAKE) -C openmpbench veryclean $Q$(RM) $(TOPDIR)/$(ARCH) $Q$(RM) $(TMP) diff --git a/hermit/usr/openmpbench/Licence.txt b/hermit/usr/openmpbench/Licence.txt new file mode 100644 index 000000000..cf0745449 --- /dev/null +++ b/hermit/usr/openmpbench/Licence.txt @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [2011] [The University of Edinburgh] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/hermit/usr/openmpbench/Makefile b/hermit/usr/openmpbench/Makefile new file mode 100644 index 000000000..e88ff3218 --- /dev/null +++ b/hermit/usr/openmpbench/Makefile @@ -0,0 +1,59 @@ +include Makefile.defs + +# If CFLAGS_CRAY is empty set it to CFLAGS +ifeq ($(CFLAGS_CRAY),) +CFLAGS_CRAY = ${CFLAGS} +endif + +%.bin: % + $(OBJCOPY_FOR_TARGET) $(OBJCOPY_FLAGS) $< $@ + +.c.o: + ${CC} ${CFLAGS} $(OMPFLAG) -c $*.c + +SYNCOBJS = syncbench.o common.o +SCHEDOBJS = schedbench.o common_sched.o +ARRAYOBJS = arraybench_$(IDA).o common.o +TASKOBJS = taskbench.o common.o +SCHEDFLAGS = -DSCHEDBENCH + +all: syncbench.bin schedbench.bin taskbench.bin + +prog: arraybench_$(IDA) + +syncbench: $(SYNCOBJS) + $(CC) -o syncbench $(LDFLAGS) $(SYNCOBJS) $(CLOCKOBJS) $(LIBS) -lm + +# Rule to ensure the lower optimisation level is picked up for common.c +# with the Cray compiler +common.o: + ${CC} ${CFLAGS_CRAY} $(OMPFLAG) -c $*.c + +# Separate rule to build common_sched.o as we need to ensure the correct +# DEFAULT_DELAY_TIME is used. +common_sched.o: + ${CC} ${CFLAGS_CRAY} $(SCHEDFLAGS) $(OMPFLAG) -o common_sched.o -c common.c + +schedbench: $(SCHEDOBJS) + $(CC) -o schedbench $(LDFLAGS) $(SCHEDOBJS) $(CLOCKOBJS) $(LIBS) -lm + +# Multiple header files due to multiple array sizes, makes header file arraybench_*.h +arraybench_$(IDA).h: arraybench.h + $(CPP) -DIDA=$(IDA) $(OMPFLAG) -P arraybench.h -o $@ + +# Multiple object files due to multiple array sizes, makes object file arraybench_*.o +arraybench_$(IDA).o: arraybench_$(IDA).h arraybench.c + $(CC) $(CFLAGS) -DIDA=$(IDA) $(OMPFLAG) arraybench.c -c -o $@ + +# Multiple executables due to multiple array sizes, makes exe file arraybench_* +arraybench_$(IDA): $(ARRAYOBJS) $(CLOCKOBJS) arraybench.c + $(CC) $(LDFLAGS) $(ARRAYOBJS) $(CLOCKOBJS) $(LIBS) -lm -o $@ + +taskbench: $(TASKOBJS) + $(CC) -o taskbench $(LDFLAGS) $(OMPFLAG) $(TASKOBJS) $(CLOCKOBJS) $(LIBS) -lm + +clean: + -rm -rf *.o syncbench schedbench arraybench_* taskbench + +veryclean: clean + -rm -rf OpenMPBench.* *.all diff --git a/hermit/usr/openmpbench/Makefile.defs b/hermit/usr/openmpbench/Makefile.defs new file mode 100644 index 000000000..4d4e65779 --- /dev/null +++ b/hermit/usr/openmpbench/Makefile.defs @@ -0,0 +1,14 @@ +# Uncomment the following line to use OpenMP 2.0 features +OMPFLAG = -DOMPVER2 +# Uncomment the following line to use OpenMP 3.0 features +#OMPFLAG = -DOMPVER2 -DOMPVER3 + +CC = $(CC_FOR_TARGET) +CFLAGS = -fopenmp $(CFLAGS_FOR_TARGET) -lm +LDFLAGS = -fopenmp $(LDFLAGS_FOR_TARGET) -lm +CPP = $(CPP_FOR_TARGET) +LIBS = + +override STRIP_DEBUG = --strip-debug #--strip-unneeded +KEEP_DEBUG = --only-keep-debug +OBJCOPY_FLAGS = -j .mboot -j .ktext -j .kdata -j .kbss -j .tbss -j .tdata -j .fini -j .init -j .ctors -j .dtors -j .text -j .data -j .rodata -j .bss -j .percore -j .eh_frame -j .jcr -j .got.plt -O binary diff --git a/hermit/usr/openmpbench/Makefile.defs.hector.cray b/hermit/usr/openmpbench/Makefile.defs.hector.cray new file mode 100644 index 000000000..a9c33a592 --- /dev/null +++ b/hermit/usr/openmpbench/Makefile.defs.hector.cray @@ -0,0 +1,10 @@ +# Uncomment the following line to use OpenMP 2.0 features +#OMPFLAG = -DOMPVER2 +# Uncomment the following line to use OpenMP 3.0 features +OMPFLAG = -DOMPVER2 -DOMPVER3 + +CC=cc +CFLAGS = -O1 -lm +LDFLAGS = -O0 -lm +CPP = /usr/bin/cpp +LIBS = diff --git a/hermit/usr/openmpbench/Makefile.defs.hector.pgi b/hermit/usr/openmpbench/Makefile.defs.hector.pgi new file mode 100644 index 000000000..346222856 --- /dev/null +++ b/hermit/usr/openmpbench/Makefile.defs.hector.pgi @@ -0,0 +1,12 @@ +# Uncomment the following line to use OpenMP 2.0 features +#OMPFLAG = -DOMPVER2 +# Uncomment the following line to use OpenMP 3.0 features +# Nested tasks don't work on HECToR Phase 3 for the PGI compiler +# and thus are disabled. +OMPFLAG = -DOMPVER2 -DOMPVER3 -DDISABLE_NESTED_TASKS_TESTS + +CC =cc +CFLAGS = -fast -mp=nonuma -lm +LDFLAGS = -fast -mp=nonuma -lm +CPP = /usr/bin/cpp +LIBS = \ No newline at end of file diff --git a/hermit/usr/openmpbench/Makefile.defs.magny0.gnu b/hermit/usr/openmpbench/Makefile.defs.magny0.gnu new file mode 100644 index 000000000..d9f5c36b1 --- /dev/null +++ b/hermit/usr/openmpbench/Makefile.defs.magny0.gnu @@ -0,0 +1,10 @@ +# Uncomment the following line to use OpenMP 2.0 features +#OMPFLAG = -DOMPVER2 +# Uncomment the following line to use OpenMP 3.0 features +OMPFLAG = -DDISABLE_BARRIER_TEST -DOMPVER2 -DOMPVER3 + +CC = /usr/local/bin/gcc-4.6 +CFLAGS = -fopenmp -O1 -lm +LDFLAGS = -fopenmp -O1 -lm +CPP = /usr/bin/cpp +LIBS = \ No newline at end of file diff --git a/hermit/usr/openmpbench/Makefile.defs.magny0.sun b/hermit/usr/openmpbench/Makefile.defs.magny0.sun new file mode 100644 index 000000000..62cbbee68 --- /dev/null +++ b/hermit/usr/openmpbench/Makefile.defs.magny0.sun @@ -0,0 +1,10 @@ +# Uncomment the following line to use OpenMP 2.0 features +#OMPFLAG = -DOMPVER2 +# Uncomment the following line to use OpenMP 3.0 features +OMPFLAG = -DOMPVER2 -DOMPVER3 + +CC = /home/h012/fiona/SolarisStudio12.2-linux-x86-tar-ML/solstudio12.2/bin/suncc +CFLAGS = -xopenmp -xO3 -lm +LDFLAGS = -xopenmp -xO3 -lm +CPP = /usr/bin/cpp +LIBS = diff --git a/hermit/usr/openmpbench/Makefile.defs.stokes.gnu b/hermit/usr/openmpbench/Makefile.defs.stokes.gnu new file mode 100644 index 000000000..8b9f0acd1 --- /dev/null +++ b/hermit/usr/openmpbench/Makefile.defs.stokes.gnu @@ -0,0 +1,10 @@ +# Uncomment the following line to use OpenMP 2.0 features +#OMPFLAG = -DOMPVER2 +# Uncomment the following line to use OpenMP 3.0 features +OMPFLAG = -DDISABLE_BARRIER_TEST -DOMPVER2 -DOMPVER3 + +CC = gcc +CFLAGS = -fopenmp -O1 -lm +LDFLAGS = -fopenmp -O1 -lm +CPP = /usr/bin/cpp +LIBS = \ No newline at end of file diff --git a/hermit/usr/openmpbench/Makefile.defs.stokes.intel b/hermit/usr/openmpbench/Makefile.defs.stokes.intel new file mode 100644 index 000000000..4d26495b4 --- /dev/null +++ b/hermit/usr/openmpbench/Makefile.defs.stokes.intel @@ -0,0 +1,10 @@ +# Uncomment the following line to use OpenMP 2.0 features +#OMPFLAG = -DOMPVER2 +# Uncomment the following line to use OpenMP 3.0 features +OMPFLAG = -DDISABLE_BARRIER_TEST -DOMPVER2 -DOMPVER3 + +CC = icc +CFLAGS = -openmp -O1 -lm +LDFLAGS = -openmp -O1 -lm +CPP = /usr/bin/cpp +LIBS = \ No newline at end of file diff --git a/hermit/usr/openmpbench/README.txt b/hermit/usr/openmpbench/README.txt new file mode 100644 index 000000000..3e89bfed4 --- /dev/null +++ b/hermit/usr/openmpbench/README.txt @@ -0,0 +1,113 @@ +/**************************************************************************** +* * +* OpenMP MicroBenchmark Suite - Version 3.1 * +* * +* produced by * +* * +* Mark Bull, Fiona Reid and Nix Mc Donnell * +* * +* at * +* * +* Edinburgh Parallel Computing Centre * +* * +* email: markb@epcc.ed.ac.uk or fiona@epcc.ed.ac.uk * +* * +* * +* This version copyright (c) The University of Edinburgh, 2015. * +* * +* * +* Licensed under the Apache License, Version 2.0 (the "License"); * +* you may not use this file except in compliance with the License. * +* You may obtain a copy of the License at * +* * +* http://www.apache.org/licenses/LICENSE-2.0 * +* * +* Unless required by applicable law or agreed to in writing, software * +* distributed under the License is distributed on an "AS IS" BASIS, * +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * +* See the License for the specific language governing permissions and * +* limitations under the License. * +* * +****************************************************************************/ + +=============== + Licence +=============== +This software is released under the licence in Licence.txt + +=============== + Introduction +=============== +Overheads due to synchronisation, loop scheduling, array operations and +task scheduling are an important factor in determining the performance of +shared memory parallel programs. We have designed a set of microbenchmarks +to measure these classes of overhead for language constructs in OpenMP. + +=============== + Installation +=============== + 1. Unpack the tar file + + 2. Edit the Makefile.defs as follows: + * Set CC to the C compiler you wish to use (e.g. gcc pgcc icc xlc etc) + * Set CFLAGS to any required C compiler flags to enable processing of + OpenMP directives (e.g. -fopenmp -mp, -omp); standard optimisation is + also recommended (e.g. -O). + * Set LDFLAGS to any required C linker flags + * Set CPP to the local C-Preprocessor (e.g. /usr/local/bin/cpp) to + make the C compiler invoke cpp on .c and .h files + * To benchmark OpenMP 2.0 features can be invoked by setting the flag + OMPFLAG = -DOMPVER2 + * To benchmark OpenMP 2.0 & 3.0 features can be invoked by setting the flag + OMPFLAG = -DOMPVER2 -DOMPVER3 + * If neither of these flags are set then OpenMP 1.0 compatibility is + ensured. + +3. Type "make" to build all 4 benchmarks or "make benchmark" where benchmark + is one of syncbench, taskbench, schedbench. By default "make" will build + executables with array sizes ranging in powers of 3 from 1 to 59049. To + build the array benchmark with an array size of arraysize, use + "make IDA=arraysize prog" where arraysize is a positive integer. + + +Example Makefile.defs.* files are supplied for several machines and +compiler versions, e.g. + Makefile.defs.hector.* - Cray XE6 + Makefile.defs.magny0.* - 48 core AMD Magny Cours machine + Makefile.defs.stokes.* - SGI Altix ICE 8200EX + + +=============== + Running +=============== + +1. Set OMP_NUM_THREADS to the number of OpenMP threads you want to run with, + e.g. export OMP_NUM_THREADS = 4 + OMP_NUM_THREADS should be less than or equal to the number of physical + cores available to you. + +2. Run the benchmark with: + ./benchmark + + The output will go to STDOUT and thus you will probably want to re-direct + this to a file. ./benchmark --help will give the usage options. + + +================= +Additional notes +================= + + 1. If you encounter problems with the value of innerreps becoming too + large (an error will be reported) try recompiling with a lower level of + optimisation, ideally with inlining turned off. + + 2. It is common to observe significant variability between the overhead + values obtained on different runs of the benchmark programs. Therefore, + it is advisable to run each benchmark, say, 10-20 times and average the + results obtained. + + 3. You should use whatever mechanisms are at your disposal to ensure that + threads have exclusive or almost exclusive access to processors. You + should rejects runs where the standard deviation or number of outliers is + large: this is a good indication that the benchmark did not have almost + exclusive access to processors. diff --git a/hermit/usr/openmpbench/arraybench.c b/hermit/usr/openmpbench/arraybench.c new file mode 100644 index 000000000..6c0d991ca --- /dev/null +++ b/hermit/usr/openmpbench/arraybench.c @@ -0,0 +1,133 @@ +/**************************************************************************** +* * +* OpenMP MicroBenchmark Suite - Version 3.1 * +* * +* produced by * +* * +* Mark Bull, Fiona Reid and Nix Mc Donnell * +* * +* at * +* * +* Edinburgh Parallel Computing Centre * +* * +* email: markb@epcc.ed.ac.uk or fiona@epcc.ed.ac.uk * +* * +* * +* This version copyright (c) The University of Edinburgh, 2015. * +* * +* * +* Licensed under the Apache License, Version 2.0 (the "License"); * +* you may not use this file except in compliance with the License. * +* You may obtain a copy of the License at * +* * +* http://www.apache.org/licenses/LICENSE-2.0 * +* * +* Unless required by applicable law or agreed to in writing, software * +* distributed under the License is distributed on an "AS IS" BASIS, * +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * +* See the License for the specific language governing permissions and * +* limitations under the License. * +* * +****************************************************************************/ + +#include +#include +#include +#include + +#include "common.h" +#include "arraybench.h" + +double btest[IDA]; +double atest[IDA]; + +#pragma omp threadprivate (btest) + +int main(int argc, char **argv) { + + init(argc, argv); + + /* GENERATE REFERENCE TIME */ + reference("reference time 1", &refer); + + char testName[32]; + + /* TEST PRIVATE */ + sprintf(testName, "PRIVATE %d", IDA); + benchmark(testName, &testprivnew); + + /* TEST FIRSTPRIVATE */ + sprintf(testName, "FIRSTPRIVATE %d", IDA); + benchmark(testName, &testfirstprivnew); + +#ifdef OMPVER2 + /* TEST COPYPRIVATE */ + sprintf(testName, "COPYPRIVATE %d", IDA); + benchmark(testName, &testcopyprivnew); +#endif + + /* TEST THREADPRIVATE - COPYIN */ + sprintf(testName, "COPYIN %d", IDA); + benchmark(testName, &testthrprivnew); + + finalise(); + + return EXIT_SUCCESS; + +} + +void refer() { + int j; + double a[1]; + for (j = 0; j < innerreps; j++) { + array_delay(delaylength, a); + } +} + +void testfirstprivnew() { + int j; + for (j = 0; j < innerreps; j++) { +#pragma omp parallel firstprivate(atest) + { + array_delay(delaylength, atest); + } + } +} + +void testprivnew() { + int j; + for (j = 0; j < innerreps; j++) { +#pragma omp parallel private(atest) + { + array_delay(delaylength, atest); + } + } +} + +#ifdef OMPVER2 +void testcopyprivnew() +{ + int j; + for (j=0; j +#include +#include +#include +#include + +#include "common.h" + +#define CONF95 1.96 + +int nthreads = -1; // Number of OpenMP threads +int delaylength = -1; // The number of iterations to delay for +int outerreps = -1; // Outer repetitions +double delaytime = -1.0; // Length of time to delay for in microseconds +double targettesttime = 0.0; // The length of time in microseconds that the test + // should run for. +unsigned long innerreps; // Inner repetitions +double *times; // Array of doubles storing the benchmark times in microseconds +double referencetime; // The average reference time in microseconds to perform + // outerreps runs +double referencesd; // The standard deviation in the reference time in + // microseconds for outerreps runs. +double testtime; // The average test time in microseconds for + // outerreps runs +double testsd; // The standard deviation in the test time in + // microseconds for outerreps runs. + +void usage(char *argv[]) { + printf("Usage: %s.x \n" + "\t--outer-repetitions (default %d)\n" + "\t--test-time (default %0.2f microseconds)\n" + "\t--delay-time (default %0.4f microseconds)\n" + "\t--delay-length " + "(default auto-generated based on processor speed)\n", + argv[0], + DEFAULT_OUTER_REPS, DEFAULT_TEST_TARGET_TIME, DEFAULT_DELAY_TIME); +} + +void parse_args(int argc, char *argv[]) { + // Parse the parameters + int arg; + for (arg = 1; arg < argc; arg++) { + if (strcmp(argv[arg], "--delay-time") == 0.0) { + delaytime = atof(argv[++arg]); + if (delaytime == 0.0) { + printf("Invalid float:--delay-time: %s\n", argv[arg]); + usage(argv); + exit(EXIT_FAILURE); + } + + } else if (strcmp(argv[arg], "--outer-repetitions") == 0) { + outerreps = atoi(argv[++arg]); + if (outerreps == 0) { + printf("Invalid integer:--outer-repetitions: %s\n", argv[arg]); + usage(argv); + exit(EXIT_FAILURE); + } + + } else if (strcmp(argv[arg], "--test-time") == 0) { + targettesttime = atof(argv[++arg]); + if (targettesttime == 0) { + printf("Invalid integer:--test-time: %s\n", argv[arg]); + usage(argv); + exit(EXIT_FAILURE); + } + + } else if (strcmp(argv[arg], "-h") == 0) { + usage(argv); + exit(EXIT_SUCCESS); + + } else { + printf("Invalid parameters: %s\n", argv[arg]); + usage(argv); + exit(EXIT_FAILURE); + } + } +} + +int getdelaylengthfromtime(double delaytime) { + int i, reps; + double lapsedtime, starttime; // seconds + + reps = 1000; + lapsedtime = 0.0; + + delaytime = delaytime/1.0E6; // convert from microseconds to seconds + + // Note: delaytime is local to this function and thus the conversion + // does not propagate to the main code. + + // Here we want to use the delaytime in microseconds to find the + // delaylength in iterations. We start with delaylength=0 and + // increase until we get a large enough delaytime, return delaylength + // in iterations. + + delaylength = 0; + delay(delaylength); + + while (lapsedtime < delaytime) { + delaylength = delaylength * 1.1 + 1; + starttime = getclock(); + for (i = 0; i < reps; i++) { + delay(delaylength); + } + lapsedtime = (getclock() - starttime) / (double) reps; + } + return delaylength; + +} + +unsigned long getinnerreps(void (*test)(void)) { + innerreps = 10L; // some initial value + double time = 0.0; + + while (time < targettesttime) { + double start = getclock(); + test(); + time = (getclock() - start) * 1.0e6; + innerreps *=2; + + // Test to stop code if compiler is optimising reference time expressions away + if (innerreps > (targettesttime*1.0e15)) { + printf("Compiler has optimised reference loop away, STOP! \n"); + printf("Try recompiling with lower optimisation level \n"); + exit(1); + } + } + return innerreps; +} + +void printheader(char *name) { + printf("\n"); + printf("--------------------------------------------------------\n"); + printf("Computing %s time using %lu reps\n", name, innerreps); +} + +void stats(double *mtp, double *sdp) { + + double meantime, totaltime, sumsq, mintime, maxtime, sd, cutoff; + + int i, nr; + + mintime = 1.0e10; + maxtime = 0.; + totaltime = 0.; + + for (i = 1; i <= outerreps; i++) { + mintime = (mintime < times[i]) ? mintime : times[i]; + maxtime = (maxtime > times[i]) ? maxtime : times[i]; + totaltime += times[i]; + } + + meantime = totaltime / outerreps; + sumsq = 0; + + for (i = 1; i <= outerreps; i++) { + sumsq += (times[i] - meantime) * (times[i] - meantime); + } + sd = sqrt(sumsq / (outerreps - 1)); + + cutoff = 3.0 * sd; + + nr = 0; + + for (i = 1; i <= outerreps; i++) { + if (fabs(times[i] - meantime) > cutoff) + nr++; + } + + printf("\n"); + printf("Sample_size Average Min Max S.D. Outliers\n"); + printf(" %d %f %f %f %f %d\n", + outerreps, meantime, mintime, maxtime, sd, nr); + printf("\n"); + + *mtp = meantime; + *sdp = sd; + +} + +void printfooter(char *name, double testtime, double testsd, + double referencetime, double refsd) { + printf("%s time = %f microseconds +/- %f\n", + name, testtime, CONF95*testsd); + printf("%s overhead = %f microseconds +/- %f\n", + name, testtime-referencetime, CONF95*(testsd+referencesd)); + +} + +void printreferencefooter(char *name, double referencetime, double referencesd) { + printf("%s time = %f microseconds +/- %f\n", + name, referencetime, CONF95 * referencesd); +} + +void init(int argc, char **argv) +{ +#pragma omp parallel + { +#pragma omp master + { + nthreads = omp_get_num_threads(); + } + + } + + parse_args(argc, argv); + + if (outerreps == -1) { + outerreps = DEFAULT_OUTER_REPS; + } + if (targettesttime == 0.0) { + targettesttime = DEFAULT_TEST_TARGET_TIME; + } + if (delaytime == -1.0) { + delaytime = DEFAULT_DELAY_TIME; + } + delaylength = getdelaylengthfromtime(delaytime); // Always need to compute delaylength in iterations + + times = malloc((outerreps+1) * sizeof(double)); + + printf("Running OpenMP benchmark version 3.0\n" + "\t%d thread(s)\n" + "\t%d outer repetitions\n" + "\t%0.2f test time (microseconds)\n" + "\t%d delay length (iterations) \n" + "\t%f delay time (microseconds)\n", + nthreads, + outerreps, targettesttime, + delaylength, delaytime); +} + +void finalise(void) { + free(times); + +} + +void initreference(char *name) { + printheader(name); + +} + +/* Calculate the reference time. */ +void reference(char *name, void (*refer)(void)) { + int k; + double start; + + // Calculate the required number of innerreps + innerreps = getinnerreps(refer); + + initreference(name); + + for (k = 0; k <= outerreps; k++) { + start = getclock(); + refer(); + times[k] = (getclock() - start) * 1.0e6 / (double) innerreps; + } + + finalisereference(name); + +} + +void finalisereference(char *name) { + stats(&referencetime, &referencesd); + printreferencefooter(name, referencetime, referencesd); + +} + +void intitest(char *name) { + printheader(name); + +} + +void finalisetest(char *name) { + stats(&testtime, &testsd); + printfooter(name, testtime, testsd, referencetime, referencesd); + +} + +/* Function to run a microbenchmark test*/ +void benchmark(char *name, void (*test)(void)) +{ + int k; + double start; + + // Calculate the required number of innerreps + innerreps = getinnerreps(test); + + intitest(name); + + for (k=0; k<=outerreps; k++) { + start = getclock(); + test(); + times[k] = (getclock() - start) * 1.0e6 / (double) innerreps; + } + + finalisetest(name); + +} + +// For the Cray compiler on HECToR we need to turn off optimisation +// for the delay and array_delay functions. Other compilers should +// not be afffected. +#pragma _CRI noopt +void delay(int delaylength) { + + int i; + float a = 0.; + + for (i = 0; i < delaylength; i++) + a += i; + if (a < 0) + printf("%f \n", a); + +} + +void array_delay(int delaylength, double a[1]) { + + int i; + a[0] = 1.0; + for (i = 0; i < delaylength; i++) + a[0] += i; + if (a[0] < 0) + printf("%f \n", a[0]); + +} +// Re-enable optimisation for remainder of source. +#pragma _CRI opt + +double getclock() { + double time; + // Returns a value in seconds of the time elapsed from some arbitrary, + // but consistent point. + double omp_get_wtime(void); + time = omp_get_wtime(); + return time; +} + +int returnfalse() { + return 0; + +} + diff --git a/hermit/usr/openmpbench/common.h b/hermit/usr/openmpbench/common.h new file mode 100644 index 000000000..df19cc4c9 --- /dev/null +++ b/hermit/usr/openmpbench/common.h @@ -0,0 +1,80 @@ +/**************************************************************************** +* * +* OpenMP MicroBenchmark Suite - Version 3.1 * +* * +* produced by * +* * +* Mark Bull, Fiona Reid and Nix Mc Donnell * +* * +* at * +* * +* Edinburgh Parallel Computing Centre * +* * +* email: markb@epcc.ed.ac.uk or fiona@epcc.ed.ac.uk * +* * +* * +* This version copyright (c) The University of Edinburgh, 2015. * +* * +* * +* Licensed under the Apache License, Version 2.0 (the "License"); * +* you may not use this file except in compliance with the License. * +* You may obtain a copy of the License at * +* * +* http://www.apache.org/licenses/LICENSE-2.0 * +* * +* Unless required by applicable law or agreed to in writing, software * +* distributed under the License is distributed on an "AS IS" BASIS, * +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * +* See the License for the specific language governing permissions and * +* limitations under the License. * +* * +****************************************************************************/ + +#ifndef COMMON_H +#define COMMON_H + +#define DEFAULT_DELAY_LENGTH -1 // -1 means the delay length should be auto generated +#define DEFAULT_OUTER_REPS 20 // Outer repetitions +#define DEFAULT_TEST_TARGET_TIME 1000.0 // Test Target time in microseconds. +#ifdef SCHEDBENCH +#define DEFAULT_DELAY_TIME 15.0 // Default delaytime in microseconds for schedbench +#else +#define DEFAULT_DELAY_TIME 0.10 // Default delaytime in microseconds +#endif + +extern int nthreads; // Number of OpenMP threads +extern int delaylength; // The number of iterations to delay for +extern int outerreps; // Outer repetitions +extern unsigned long innerreps; // Inner repetitions +extern double delaytime; // Delay time in microseconds +extern double targettesttime; // The length of time in microseconds the test + // should run for +extern double *times; // Array to store results in + +void init(int argc, char **argv); + +void initreference(char *name); + +void finalisereference(char *name); + +void intitest(char *name); + +void finalisetest(char *name); + +double getclock(); + +void delay(int delaylength); + +void array_delay(int delaylength, double a[1]); + +int getdelaylengthfromtime(double delaytime); + +int returnfalse(void); + +void finalise(void); + +void benchmark(char *name, void (*test)(void)); + +void reference(char *name, void (*refer)(void)); + +#endif //COMMON_H diff --git a/hermit/usr/openmpbench/schedbench.c b/hermit/usr/openmpbench/schedbench.c new file mode 100644 index 000000000..9841642fb --- /dev/null +++ b/hermit/usr/openmpbench/schedbench.c @@ -0,0 +1,145 @@ +/**************************************************************************** +* * +* OpenMP MicroBenchmark Suite - Version 3.1 * +* * +* produced by * +* * +* Mark Bull, Fiona Reid and Nix Mc Donnell * +* * +* at * +* * +* Edinburgh Parallel Computing Centre * +* * +* email: markb@epcc.ed.ac.uk or fiona@epcc.ed.ac.uk * +* * +* * +* This version copyright (c) The University of Edinburgh, 2015. * +* * +* * +* Licensed under the Apache License, Version 2.0 (the "License"); * +* you may not use this file except in compliance with the License. * +* You may obtain a copy of the License at * +* * +* http://www.apache.org/licenses/LICENSE-2.0 * +* * +* Unless required by applicable law or agreed to in writing, software * +* distributed under the License is distributed on an "AS IS" BASIS, * +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * +* See the License for the specific language governing permissions and * +* limitations under the License. * +* * +****************************************************************************/ + + +#include +#include +#include +#include + +#include "common.h" +#include "schedbench.h" + +int cksz, itersperthr = 128; +char testName[32]; + +int main(int argc, char **argv) { + + init(argc, argv); + + /* GENERATE REFERENCE TIME */ + reference("reference time", &refer); + + /* TEST STATIC */ + benchmark("STATIC", &teststatic); + + /* TEST STATIC,n */ + cksz = 1; + while (cksz <= itersperthr) { + sprintf(testName, "STATIC %d", cksz); + benchmark(testName, &teststaticn); + cksz *= 2; + } + + /* TEST DYNAMIC,n */ + cksz = 1; + while (cksz <= itersperthr) { + sprintf(testName, "DYNAMIC %d", cksz); + benchmark(testName, &testdynamicn); + cksz *= 2; + } + + /* TEST GUIDED,n */ + cksz = 1; + while (cksz <= itersperthr / nthreads) { + sprintf(testName, "GUIDED %d", cksz); + benchmark(testName, &testguidedn); + cksz *= 2; + } + + finalise(); + + return EXIT_SUCCESS; + +} + +void refer() { + int i, j; + for (j = 0; j < innerreps; j++) { + for (i = 0; i < itersperthr; i++) { + delay(delaylength); + } + } +} + +void teststatic() { + + int i, j; +#pragma omp parallel private(j) + { + for (j = 0; j < innerreps; j++) { +#pragma omp for schedule(static) + for (i = 0; i < itersperthr * nthreads; i++) { + delay(delaylength); + } + } + } +} + +void teststaticn() { + int i, j; +#pragma omp parallel private(j) + { + for (j = 0; j < innerreps; j++) { +#pragma omp for schedule(static,cksz) + for (i = 0; i < itersperthr * nthreads; i++) { + delay(delaylength); + } + } + } +} + +void testdynamicn() { + int i, j; +#pragma omp parallel private(j) + { + for (j = 0; j < innerreps; j++) { +#pragma omp for schedule(dynamic,cksz) + for (i = 0; i < itersperthr * nthreads; i++) { + delay(delaylength); + } + } + } +} + +void testguidedn() { + int i, j; +#pragma omp parallel private(j) + { + for (j = 0; j < innerreps; j++) { +#pragma omp for schedule(guided,cksz) + for (i = 0; i < itersperthr * nthreads; i++) { + delay(delaylength); + } + } + } +} diff --git a/hermit/usr/openmpbench/schedbench.h b/hermit/usr/openmpbench/schedbench.h new file mode 100644 index 000000000..28ef9299a --- /dev/null +++ b/hermit/usr/openmpbench/schedbench.h @@ -0,0 +1,46 @@ +/**************************************************************************** +* * +* OpenMP MicroBenchmark Suite - Version 3.1 * +* * +* produced by * +* * +* Mark Bull, Fiona Reid and Nix Mc Donnell * +* * +* at * +* * +* Edinburgh Parallel Computing Centre * +* * +* email: markb@epcc.ed.ac.uk or fiona@epcc.ed.ac.uk * +* * +* * +* This version copyright (c) The University of Edinburgh, 2015. * +* * +* * +* Licensed under the Apache License, Version 2.0 (the "License"); * +* you may not use this file except in compliance with the License. * +* You may obtain a copy of the License at * +* * +* http://www.apache.org/licenses/LICENSE-2.0 * +* * +* Unless required by applicable law or agreed to in writing, software * +* distributed under the License is distributed on an "AS IS" BASIS, * +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * +* See the License for the specific language governing permissions and * +* limitations under the License. * +* * +****************************************************************************/ + +#ifndef SCHEDBENCH_H +#define SCHEDBENCH_H + +void refer(void); + +void teststatic(void); + +void teststaticn(void); + +void testdynamicn(void); + +void testguidedn(void); + +#endif //SCHEDBENCH_H diff --git a/hermit/usr/openmpbench/syncbench.c b/hermit/usr/openmpbench/syncbench.c new file mode 100644 index 000000000..b8f0d9ae6 --- /dev/null +++ b/hermit/usr/openmpbench/syncbench.c @@ -0,0 +1,253 @@ +/**************************************************************************** +* * +* OpenMP MicroBenchmark Suite - Version 3.1 * +* * +* produced by * +* * +* Mark Bull, Fiona Reid and Nix Mc Donnell * +* * +* at * +* * +* Edinburgh Parallel Computing Centre * +* * +* email: markb@epcc.ed.ac.uk or fiona@epcc.ed.ac.uk * +* * +* * +* This version copyright (c) The University of Edinburgh, 2015. * +* * +* * +* Licensed under the Apache License, Version 2.0 (the "License"); * +* you may not use this file except in compliance with the License. * +* You may obtain a copy of the License at * +* * +* http://www.apache.org/licenses/LICENSE-2.0 * +* * +* Unless required by applicable law or agreed to in writing, software * +* distributed under the License is distributed on an "AS IS" BASIS, * +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * +* See the License for the specific language governing permissions and * +* limitations under the License. * +* * +****************************************************************************/ + +#include +#include +#include +#include + +#include "common.h" +#include "syncbench.h" + +omp_lock_t lock; + +int main(int argc, char **argv) { + + // Start Paraver tracing +#ifdef PARAVERTRACE + Extrae_init(); +#endif + + init(argc, argv); + + omp_init_lock(&lock); + + /* GENERATE REFERENCE TIME */ + reference("reference time 1", &refer); + + /* TEST PARALLEL REGION */ + benchmark("PARALLEL", &testpr); + + /* TEST FOR */ + benchmark("FOR", &testfor); + + /* TEST PARALLEL FOR */ + benchmark("PARALLEL FOR", &testpfor); + + /* TEST BARRIER */ + benchmark("BARRIER", &testbar); + + /* TEST SINGLE */ + benchmark("SINGLE", &testsing); + + /* TEST CRITICAL*/ + benchmark("CRITICAL", &testcrit); + + /* TEST LOCK/UNLOCK */ + benchmark("LOCK/UNLOCK", &testlock); + + /* TEST ORDERED SECTION */ + benchmark("ORDERED", &testorder); + + /* GENERATE NEW REFERENCE TIME */ + reference("reference time 2", &referatom); + + /* TEST ATOMIC */ + benchmark("ATOMIC", &testatom); + + /* GENERATE NEW REFERENCE TIME */ + reference("reference time 3", &referred); + + /* TEST REDUCTION (1 var) */ + benchmark("REDUCTION", &testred); + +#ifdef PARAVERTRACE + Extrae_fini(); +#endif + + finalise(); + + return EXIT_SUCCESS; +} + +void refer() { + int j; + for (j = 0; j < innerreps; j++) { + delay(delaylength); + } +} + +void referatom(){ + int j; + double aaaa = 0.0; + double epsilon = 1.0e-15; + double b, c; + b = 1.0; + c = (1.0 + epsilon); + for (j = 0; j < innerreps; j++) { + aaaa += b; + b *= c; + } + if (aaaa < 0.0) + printf("%f\n", aaaa); +} + +void referred() { + int j; + int aaaa = 0; + for (j = 0; j < innerreps; j++) { + delay(delaylength); + aaaa += 1; + } +} + +void testpr() { + int j; + for (j = 0; j < innerreps; j++) { +#pragma omp parallel + { + delay(delaylength); + } + } +} + +void testfor() { + int i, j; +#pragma omp parallel private(j) + { + for (j = 0; j < innerreps; j++) { +#pragma omp for + for (i = 0; i < nthreads; i++) { + delay(delaylength); + } + } + } +} + +void testpfor() { + int i, j; + for (j = 0; j < innerreps; j++) { +#pragma omp parallel for + for (i = 0; i < nthreads; i++) { + delay(delaylength); + } + } +} + +void testbar() { + int j; +#pragma omp parallel private(j) + { + for (j = 0; j < innerreps; j++) { + delay(delaylength); +#pragma omp barrier + } + } +} + +void testsing() { + int j; +#pragma omp parallel private(j) + { + for (j = 0; j < innerreps; j++) { +#pragma omp single + delay(delaylength); + } + } +} + +void testcrit() { + int j; +#pragma omp parallel private(j) + { + for (j = 0; j < innerreps / nthreads; j++) { +#pragma omp critical + { + delay(delaylength); + } + } + } +} + +void testlock() { + int j; + +#pragma omp parallel private(j) + { + for (j = 0; j < innerreps / nthreads; j++) { + omp_set_lock(&lock); + delay(delaylength); + omp_unset_lock(&lock); + } + } +} + +void testorder() { + int j; +#pragma omp parallel for ordered schedule (static,1) + for (j = 0; j < (int)innerreps; j++) { +#pragma omp ordered + delay(delaylength); + } +} + +void testatom() { + int j; + double aaaa = 0.0; + double epsilon = 1.0e-15; + double b,c; + b = 1.0; + c = (1.0 + epsilon); +#pragma omp parallel private(j) firstprivate(b) + { + for (j = 0; j < innerreps / nthreads; j++) { +#pragma omp atomic + aaaa += b; + b *= c; + } + } + if (aaaa < 0.0) + printf("%f\n", aaaa); +} + +void testred() { + int j; + int aaaa = 0; + for (j = 0; j < innerreps; j++) { +#pragma omp parallel reduction(+:aaaa) + { + delay(delaylength); + aaaa += 1; + } + } +} + diff --git a/hermit/usr/openmpbench/syncbench.h b/hermit/usr/openmpbench/syncbench.h new file mode 100644 index 000000000..1e2bfeeb2 --- /dev/null +++ b/hermit/usr/openmpbench/syncbench.h @@ -0,0 +1,63 @@ +/**************************************************************************** +* * +* OpenMP MicroBenchmark Suite - Version 3.1 * +* * +* produced by * +* * +* Mark Bull, Fiona Reid and Nix Mc Donnell * +* * +* at * +* * +* Edinburgh Parallel Computing Centre * +* * +* email: markb@epcc.ed.ac.uk or fiona@epcc.ed.ac.uk * +* * +* * +* This version copyright (c) The University of Edinburgh, 2015. * +* * +* * +* Licensed under the Apache License, Version 2.0 (the "License"); * +* you may not use this file except in compliance with the License. * +* You may obtain a copy of the License at * +* * +* http://www.apache.org/licenses/LICENSE-2.0 * +* * +* Unless required by applicable law or agreed to in writing, software * +* distributed under the License is distributed on an "AS IS" BASIS, * +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * +* See the License for the specific language governing permissions and * +* limitations under the License. * +* * +****************************************************************************/ + + +#ifndef SYNCBENCH_H +#define SYNCBENCH_H + +void refer(void); + +void referatom(void); + +void referred(void); + +void testpr(void); + +void testfor(void); + +void testpfor(void); + +void testbar(void); + +void testsing(void); + +void testcrit(void); + +void testlock(void); + +void testorder(void); + +void testatom(void); + +void testred(void); + +#endif //SYNCBENCH_H diff --git a/hermit/usr/openmpbench/taskbench.c b/hermit/usr/openmpbench/taskbench.c new file mode 100644 index 000000000..cd5aa6a0f --- /dev/null +++ b/hermit/usr/openmpbench/taskbench.c @@ -0,0 +1,331 @@ +/**************************************************************************** +* * +* OpenMP MicroBenchmark Suite - Version 3.1 * +* * +* produced by * +* * +* Mark Bull, Fiona Reid and Nix Mc Donnell * +* * +* at * +* * +* Edinburgh Parallel Computing Centre * +* * +* email: markb@epcc.ed.ac.uk or fiona@epcc.ed.ac.uk * +* * +* * +* This version copyright (c) The University of Edinburgh, 2015. * +* * +* * +* Licensed under the Apache License, Version 2.0 (the "License"); * +* you may not use this file except in compliance with the License. * +* You may obtain a copy of the License at * +* * +* http://www.apache.org/licenses/LICENSE-2.0 * +* * +* Unless required by applicable law or agreed to in writing, software * +* distributed under the License is distributed on an "AS IS" BASIS, * +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * +* See the License for the specific language governing permissions and * +* limitations under the License. * +* * +****************************************************************************/ + +#include +#include +#include + +#include "common.h" +#include "taskbench.h" + +#define DEPTH 6 + +int main(int argc, char **argv) { + + init(argc, argv); + +#ifdef OMPVER3 + + /* GENERATE REFERENCE TIME */ + reference("reference time 1", &refer); + + /* TEST PARALLEL TASK GENERATION */ + benchmark("PARALLEL TASK", &testParallelTaskGeneration); + + /* TEST MASTER TASK GENERATION */ + benchmark("MASTER TASK", &testMasterTaskGeneration); + + /* TEST MASTER TASK GENERATION WITH BUSY SLAVES */ + benchmark("MASTER TASK BUSY SLAVES", &testMasterTaskGenerationWithBusySlaves); + + /* TEST CONDITIONAL TASK GENERATION */ +#ifndef DISABLE_CONDITIONAL_TASK_TEST + benchmark("CONDITIONAL TASK", &testConditionalTaskGeneration); +#endif // DISABLE_CONDITIONAL_TASK_TEST + + /* TEST TASK WAIT */ + benchmark("TASK WAIT", &testTaskWait); + + /* TEST TASK BARRIER */ +#ifndef DISABLE_BARRIER_TEST + benchmark("TASK BARRIER", &testTaskBarrier); +#endif //DISABLE_BARRIER_TEST + +#ifndef DISABLE_NESTED_TASKS_TESTS + /* TEST NESTED TASK GENERATION */ + benchmark("NESTED TASK", &testNestedTaskGeneration); + + /* TEST NESTED MASTER TASK GENERATION */ + benchmark("NESTED MASTER TASK", &testNestedMasterTaskGeneration); + +#endif // DISABLE_NESTED_TASKS_TESTS + + /* GENERATE THE SECOND REFERENCE TIME */ + reference("reference time 2", &refer); + + /* TEST BRANCH TASK TREE */ + benchmark("BRANCH TASK TREE", &testBranchTaskGeneration); + + /* TEST LEAF TASK TREE */ + benchmark("LEAF TASK TREE", &testLeafTaskGeneration); + +#endif // OMPVER3 + + finalise(); + + return EXIT_SUCCESS; + +} + +/* Calculate the reference time. */ +void refer() { + int j; + for (j = 0; j < innerreps; j++) { + delay(delaylength); + } + +} + +/* Calculate the second reference time. */ +void refer2() { + int j; + for (j = 0; j < (innerreps >> DEPTH) * (1 << DEPTH); j++) { + delay(delaylength); + }; + +} + +/* Test parallel task generation overhead */ +void testParallelTaskGeneration() { + int j; +#pragma omp parallel private( j ) + { + for ( j = 0; j < innerreps; j ++ ) { +#pragma omp task + { + delay( delaylength ); + + } // task + }; // for j + } // parallel + +} + +/* Test master task generation overhead */ +void testMasterTaskGeneration() { + int j; +#pragma omp parallel private(j) + { +#pragma omp master + { + /* Since this is executed by one thread we need innerreps * nthreads + iterations */ + for (j = 0; j < innerreps * nthreads; j++) { +#pragma omp task + { + delay(delaylength); + + } + + } /* End for j */ + } /* End master */ + } /* End parallel */ + +} + +/* Test master task generation overhead when the slave threads are busy */ +void testMasterTaskGenerationWithBusySlaves() { + int j; +#pragma omp parallel private( j ) + { + int thread_num = omp_get_thread_num(); + for (j = 0; j < innerreps; j ++ ) { + + if ( thread_num == 0 ) { +#pragma omp task + { + delay( delaylength ); + } // task + + } else { + delay( delaylength ); + + }; // if + }; // for j + } // parallel +} + +/* Measure overhead of checking if a task should be spawned. */ +void testConditionalTaskGeneration() { + int j; +#pragma omp parallel private(j) + { + for (j = 0; j < innerreps; j++) { +#pragma omp task if(returnfalse()) + { + delay( delaylength ); + } + } + } +} + +#ifndef DISABLE_NESTED_TASKS_TESTS + +/* Measure overhead of nested tasks (all threads construct outer tasks) */ +void testNestedTaskGeneration() { + int i,j; +#pragma omp parallel private( i, j ) + { + for ( j = 0; j < innerreps / nthreads; j ++ ) { +#pragma omp task private( i ) + { + for ( i = 0; i < nthreads; i ++ ) { +#pragma omp task untied + { + delay( delaylength ); + + } // task + }; // for i + + // wait for inner tasks to complete +#pragma omp taskwait + + } // task + }; // for j + } // parallel +} + +/* Measure overhead of nested tasks (master thread constructs outer tasks) */ +void testNestedMasterTaskGeneration() { + int i, j; +#pragma omp parallel private( i, j ) + { +#pragma omp master + { + for ( j = 0; j < innerreps; j ++ ) { +#pragma omp task private( i ) + { + for ( i = 0; i < nthreads; i ++ ) { +#pragma omp task + { + delay( delaylength ); + + } // task + }; // for i + + // wait for inner tasks to complete +#pragma omp taskwait + + } // task + }; // for j + } // master + } // parallel +} +#endif // DISABLE_NESTED_TASKS_TESTS + +/* Measure overhead of taskwait (all threads construct tasks) */ +void testTaskWait() { + int j; +#pragma omp parallel private( j ) + { + for ( j = 0; j < innerreps; j ++ ) { +#pragma omp task + { + delay( delaylength ); + + } // task +#pragma omp taskwait + + }; // for j + } // parallel +} + +/* Measure overhead of tasking barrier (all threads construct tasks) */ +void testTaskBarrier() { + int j; +#pragma omp parallel private( j ) + { + for ( j = 0; j < innerreps; j ++ ) { +#pragma omp task + { + delay( delaylength ); + + } // task +#pragma omp barrier + + }; // for j + } // parallel +} + +/* Test parallel task generation overhead where work is done at all levels. */ +void testBranchTaskGeneration() { + int j; +#pragma omp parallel private(j) + { + for (j = 0; j < (innerreps >> DEPTH); j++) { +#pragma omp task + { + branchTaskTree(DEPTH); + delay(delaylength); + } + + } + } +} + +void branchTaskTree(int tree_level) { + if ( tree_level > 0 ) { +#pragma omp task + { + branchTaskTree(tree_level - 1); + branchTaskTree(tree_level - 1); + delay(delaylength); + } + } +} + +/* Test parallel task generation overhead where work is done only at the leaf level. */ +void testLeafTaskGeneration() { + int j; +#pragma omp parallel private(j) + { + for (j = 0; j < (innerreps >> DEPTH); j++) { + leafTaskTree(DEPTH); + + } + } + +} + +void leafTaskTree(int tree_level) { + if ( tree_level == 0 ) { + delay(delaylength); + + } else { +#pragma omp task + { + leafTaskTree(tree_level - 1); + leafTaskTree(tree_level - 1); + } + } +} + diff --git a/hermit/usr/openmpbench/taskbench.h b/hermit/usr/openmpbench/taskbench.h new file mode 100644 index 000000000..f8da08b0c --- /dev/null +++ b/hermit/usr/openmpbench/taskbench.h @@ -0,0 +1,66 @@ +/**************************************************************************** +* * +* OpenMP MicroBenchmark Suite - Version 3.1 * +* * +* produced by * +* * +* Mark Bull, Fiona Reid and Nix Mc Donnell * +* * +* at * +* * +* Edinburgh Parallel Computing Centre * +* * +* email: markb@epcc.ed.ac.uk or fiona@epcc.ed.ac.uk * +* * +* * +* This version copyright (c) The University of Edinburgh, 2015. * +* * +* * +* Licensed under the Apache License, Version 2.0 (the "License"); * +* you may not use this file except in compliance with the License. * +* You may obtain a copy of the License at * +* * +* http://www.apache.org/licenses/LICENSE-2.0 * +* * +* Unless required by applicable law or agreed to in writing, software * +* distributed under the License is distributed on an "AS IS" BASIS, * +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * +* See the License for the specific language governing permissions and * +* limitations under the License. * +* * +****************************************************************************/ + +#ifndef TASKBENCH_H +#define TASKBENCH_H + +void refer(void); + +void refer2(void); + +void stats(double*, double*); + +void testParallelTaskGeneration(void); + +void testMasterTaskGeneration(void); + +void testMasterTaskGenerationWithBusySlaves(void); + +void testNestedTaskGeneration(void); + +void testNestedMasterTaskGeneration(void); + +void testTaskWait(void); + +void testTaskBarrier(void); + +void testConditionalTaskGeneration(void); + +void testBranchTaskGeneration(void); + +void branchTaskTree(int tree_level); + +void testLeafTaskGeneration(void); + +void leafTaskTree(int tree_level); + +#endif //TASKBENCH_H