1
0
Fork 0
mirror of https://github.com/hermitcore/libhermit.git synced 2025-03-09 00:00:03 +01:00

add EPCC OpenMP micro-benchmark suite 3.1

This commit is contained in:
Stefan Lankes 2016-03-08 19:10:51 +01:00
parent ab4d1fda73
commit fedd9df9a8
22 changed files with 1998 additions and 1 deletions

View file

@ -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

View file

@ -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)

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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 =

View file

@ -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 =

View file

@ -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 =

View file

@ -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 =

View file

@ -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 =

View file

@ -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 =

View file

@ -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.

View file

@ -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 <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <omp.h>
#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<innerreps; j++) {
#pragma omp parallel private(atest)
{
#pragma omp single copyprivate(atest)
{
array_delay(delaylength, atest);
}
}
}
}
#endif
void testthrprivnew() {
int j;
for (j = 0; j < innerreps; j++) {
#pragma omp parallel copyin(btest)
{
array_delay(delaylength, btest);
}
}
}

View file

@ -0,0 +1,52 @@
/****************************************************************************
* *
* 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 ARRAYBENCH_H
#define ARRAYBENCH_H
void refer();
void testfirstprivnew();
void testprivnew();
#ifdef OMPVER2
void testcopyprivnew();
#endif
void testthrprivnew();
void stats(double*, double*);
#endif //ARRAYBENCH_H

View file

@ -0,0 +1,374 @@
/****************************************************************************
* *
* 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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <omp.h>
#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 <outer-repetitions> (default %d)\n"
"\t--test-time <target-test-time> (default %0.2f microseconds)\n"
"\t--delay-time <delay-time> (default %0.4f microseconds)\n"
"\t--delay-length <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;
}

View file

@ -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

View file

@ -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 <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <omp.h>
#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);
}
}
}
}

View file

@ -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

View file

@ -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 <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <omp.h>
#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;
}
}
}

View file

@ -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

View file

@ -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 <stdio.h>
#include <stdlib.h>
#include <omp.h>
#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);
}
}
}

View file

@ -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