Offer API for setting number of loop dispatch buffers
The problem is the lack of dispatch buffers when thousands of loops with nowait, about 10 iterations each, are executed by hundreds of threads. We only have built-in 7 dispatch buffers, but there is a need in dozens or hundreds of buffers. The problem can be fixed by setting KMP_MAX_DISP_BUF to bigger value. In order to give users same possibility I changed build-time control into run-time one, adding API just in case. This change adds an environment variable KMP_DISP_NUM_BUFFERS and a new API function kmp_set_disp_num_buffers(int num_buffers). The KMP_DISP_NUM_BUFFERS envirable works only before serial initialization, because during the serial initialization we already allocate buffers for the hot team, so it is too late to change the number of buffers later (or we need to reallocate buffers for all teams which sounds too complicated). The kmp_set_defaults() routine does not work for this envirable, because it calls serial initialization before reading the parameter string. So a new routine, kmp_set_disp_num_buffers(), is created so that it can set our internal global variable before the library initialization. If both the envirable and API used the envirable wins. Differential Revision: http://reviews.llvm.org/D20697 git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@271318 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -397,6 +397,7 @@ kmpc_set_defaults 224
|
||||
%endif
|
||||
%endif
|
||||
kmpc_aligned_malloc 265
|
||||
kmpc_set_disp_num_buffers 267
|
||||
|
||||
# User API entry points that have both lower- and upper- case versions for Fortran.
|
||||
# Number for lowercase version is indicated. Number for uppercase is obtained by adding 1000.
|
||||
@@ -528,6 +529,8 @@ kmp_set_warnings_off 780
|
||||
%endif
|
||||
%endif # OMP_41
|
||||
|
||||
kmp_set_disp_num_buffers 890
|
||||
|
||||
%ifndef stub
|
||||
# Ordinals between 900 and 999 are reserved
|
||||
|
||||
|
||||
@@ -408,6 +408,7 @@ AffThrPlaceDeprecated "KMP_PLACE_THREADS \"o\" offset designator deprecat
|
||||
AffUsingHwloc "%1$s: Affinity capable, using hwloc."
|
||||
AffIgnoringHwloc "%1$s: Ignoring hwloc mechanism."
|
||||
AffHwlocErrorOccurred "%1$s: Hwloc failed in %2$s. Relying on internal affinity mechanisms."
|
||||
EnvSerialWarn "%1$s must be set prior to OpenMP runtime library initialization; ignored."
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -140,6 +140,7 @@
|
||||
extern void __KAI_KMPC_CONVENTION kmp_set_library_turnaround (void);
|
||||
extern void __KAI_KMPC_CONVENTION kmp_set_library_throughput (void);
|
||||
extern void __KAI_KMPC_CONVENTION kmp_set_defaults (char const *);
|
||||
extern void __KAI_KMPC_CONVENTION kmp_set_disp_num_buffers (int);
|
||||
|
||||
/* Intel affinity API */
|
||||
typedef void * kmp_affinity_mask_t;
|
||||
|
||||
@@ -410,6 +410,11 @@
|
||||
integer (kind=omp_integer_kind) kmp_get_library
|
||||
end function kmp_get_library
|
||||
|
||||
subroutine kmp_set_disp_num_buffers(num) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind), value :: num
|
||||
end subroutine kmp_set_disp_num_buffers
|
||||
|
||||
function kmp_set_affinity(mask) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) kmp_set_affinity
|
||||
|
||||
@@ -391,6 +391,11 @@
|
||||
integer (kind=omp_integer_kind) kmp_get_library
|
||||
end function kmp_get_library
|
||||
|
||||
subroutine kmp_set_disp_num_buffers(num) bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind), value :: num
|
||||
end subroutine kmp_set_disp_num_buffers
|
||||
|
||||
function kmp_set_affinity(mask) bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) kmp_set_affinity
|
||||
@@ -544,6 +549,7 @@
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_get_stacksize_s
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_get_blocktime
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_get_library
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_set_disp_num_buffers
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_set_affinity
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_get_affinity
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_get_affinity_max_proc
|
||||
@@ -615,6 +621,7 @@
|
||||
!$omp declare target(kmp_get_stacksize_s )
|
||||
!$omp declare target(kmp_get_blocktime )
|
||||
!$omp declare target(kmp_get_library )
|
||||
!$omp declare target(kmp_set_disp_num_buffers )
|
||||
!$omp declare target(kmp_set_affinity )
|
||||
!$omp declare target(kmp_get_affinity )
|
||||
!$omp declare target(kmp_get_affinity_max_proc )
|
||||
|
||||
+3
-2
@@ -1050,8 +1050,7 @@ extern int __kmp_place_num_threads_per_core;
|
||||
#define KMP_MAX_NEXT_WAIT (INT_MAX/2)
|
||||
#define KMP_DEFAULT_NEXT_WAIT 1024U
|
||||
|
||||
// max possible dynamic loops in concurrent execution per team
|
||||
#define KMP_MAX_DISP_BUF 7
|
||||
#define KMP_DFLT_DISP_NUM_BUFF 7
|
||||
#define KMP_MAX_ORDERED 8
|
||||
|
||||
#define KMP_MAX_FIELDS 32
|
||||
@@ -2806,6 +2805,7 @@ extern kmp_uint32 __kmp_init_mxcsr; /* init thread's mxscr */
|
||||
#endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
|
||||
|
||||
extern int __kmp_dflt_max_active_levels; /* max_active_levels for nested parallelism enabled by default a la OMP_MAX_ACTIVE_LEVELS */
|
||||
extern int __kmp_dispatch_num_buffers; /* max possible dynamic loops in concurrent execution per team */
|
||||
#if KMP_NESTED_HOT_TEAMS
|
||||
extern int __kmp_hot_teams_mode;
|
||||
extern int __kmp_hot_teams_max_level;
|
||||
@@ -3623,6 +3623,7 @@ KMP_EXPORT void KMPC_CONVENTION kmpc_set_stacksize(int);
|
||||
KMP_EXPORT void KMPC_CONVENTION kmpc_set_stacksize_s(size_t);
|
||||
KMP_EXPORT void KMPC_CONVENTION kmpc_set_library(int);
|
||||
KMP_EXPORT void KMPC_CONVENTION kmpc_set_defaults(char const *);
|
||||
KMP_EXPORT void KMPC_CONVENTION kmpc_set_disp_num_buffers(int);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1653,6 +1653,15 @@ kmpc_set_defaults( char const * str )
|
||||
__kmp_aux_set_defaults( str, KMP_STRLEN( str ) );
|
||||
}
|
||||
|
||||
void
|
||||
kmpc_set_disp_num_buffers( int arg )
|
||||
{
|
||||
// ignore after initialization because some teams have already
|
||||
// allocated dispatch buffers
|
||||
if( __kmp_init_serial == 0 && arg > 0 )
|
||||
__kmp_dispatch_num_buffers = arg;
|
||||
}
|
||||
|
||||
int
|
||||
kmpc_set_affinity_mask_proc( int proc, void **mask )
|
||||
{
|
||||
@@ -3061,7 +3070,7 @@ __kmpc_doacross_init(ident_t *loc, int gtid, int num_dims, struct kmp_dim * dims
|
||||
}
|
||||
KMP_DEBUG_ASSERT(team->t.t_nproc > 1);
|
||||
idx = pr_buf->th_doacross_buf_idx++; // Increment index of shared buffer for the next loop
|
||||
sh_buf = &team->t.t_disp_buffer[idx % KMP_MAX_DISP_BUF];
|
||||
sh_buf = &team->t.t_disp_buffer[idx % __kmp_dispatch_num_buffers];
|
||||
|
||||
// Save bounds info into allocated private buffer
|
||||
KMP_DEBUG_ASSERT(pr_buf->th_doacross_info == NULL);
|
||||
@@ -3111,7 +3120,7 @@ __kmpc_doacross_init(ident_t *loc, int gtid, int num_dims, struct kmp_dim * dims
|
||||
}
|
||||
KMP_DEBUG_ASSERT(trace_count > 0);
|
||||
|
||||
// Check if shared buffer is not occupied by other loop (idx - KMP_MAX_DISP_BUF)
|
||||
// Check if shared buffer is not occupied by other loop (idx - __kmp_dispatch_num_buffers)
|
||||
if( idx != sh_buf->doacross_buf_idx ) {
|
||||
// Shared buffer is occupied, wait for it to be free
|
||||
__kmp_wait_yield_4( (kmp_uint32*)&sh_buf->doacross_buf_idx, idx, __kmp_eq_4, NULL );
|
||||
@@ -3300,14 +3309,14 @@ __kmpc_doacross_fini(ident_t *loc, int gtid)
|
||||
if( num_done == th->th.th_team_nproc ) {
|
||||
// we are the last thread, need to free shared resources
|
||||
int idx = pr_buf->th_doacross_buf_idx - 1;
|
||||
dispatch_shared_info_t *sh_buf = &team->t.t_disp_buffer[idx % KMP_MAX_DISP_BUF];
|
||||
dispatch_shared_info_t *sh_buf = &team->t.t_disp_buffer[idx % __kmp_dispatch_num_buffers];
|
||||
KMP_DEBUG_ASSERT(pr_buf->th_doacross_info[1] == (kmp_int64)&sh_buf->doacross_num_done);
|
||||
KMP_DEBUG_ASSERT(num_done == (kmp_int64)sh_buf->doacross_num_done);
|
||||
KMP_DEBUG_ASSERT(idx == sh_buf->doacross_buf_idx);
|
||||
__kmp_thread_free(th, (void*)sh_buf->doacross_flags);
|
||||
sh_buf->doacross_flags = NULL;
|
||||
sh_buf->doacross_num_done = 0;
|
||||
sh_buf->doacross_buf_idx += KMP_MAX_DISP_BUF; // free buffer for future re-use
|
||||
sh_buf->doacross_buf_idx += __kmp_dispatch_num_buffers; // free buffer for future re-use
|
||||
}
|
||||
// free private resources (need to keep buffer index forever)
|
||||
__kmp_thread_free(th, (void*)pr_buf->th_doacross_info);
|
||||
|
||||
@@ -656,9 +656,9 @@ __kmp_dispatch_init(
|
||||
|
||||
/* What happens when number of threads changes, need to resize buffer? */
|
||||
pr = reinterpret_cast< dispatch_private_info_template< T > * >
|
||||
( &th -> th.th_dispatch -> th_disp_buffer[ my_buffer_index % KMP_MAX_DISP_BUF ] );
|
||||
( &th -> th.th_dispatch -> th_disp_buffer[ my_buffer_index % __kmp_dispatch_num_buffers ] );
|
||||
sh = reinterpret_cast< dispatch_shared_info_template< UT > volatile * >
|
||||
( &team -> t.t_disp_buffer[ my_buffer_index % KMP_MAX_DISP_BUF ] );
|
||||
( &team -> t.t_disp_buffer[ my_buffer_index % __kmp_dispatch_num_buffers ] );
|
||||
}
|
||||
|
||||
/* Currently just ignore the monotonic and non-monotonic modifiers (the compiler isn't producing them
|
||||
@@ -2150,7 +2150,7 @@ __kmp_dispatch_next(
|
||||
|
||||
KMP_MB(); /* Flush all pending memory write invalidates. */
|
||||
|
||||
sh -> buffer_index += KMP_MAX_DISP_BUF;
|
||||
sh -> buffer_index += __kmp_dispatch_num_buffers;
|
||||
KD_TRACE(100, ("__kmp_dispatch_next: T#%d change buffer_index:%d\n",
|
||||
gtid, sh->buffer_index) );
|
||||
|
||||
|
||||
@@ -215,6 +215,19 @@ FTN_GET_LIBRARY (void)
|
||||
#endif
|
||||
}
|
||||
|
||||
void FTN_STDCALL
|
||||
FTN_SET_DISP_NUM_BUFFERS( int KMP_DEREF arg )
|
||||
{
|
||||
#ifdef KMP_STUB
|
||||
; // empty routine
|
||||
#else
|
||||
// ignore after initialization because some teams have already
|
||||
// allocated dispatch buffers
|
||||
if( __kmp_init_serial == 0 && (KMP_DEREF arg) > 0 )
|
||||
__kmp_dispatch_num_buffers = KMP_DEREF arg;
|
||||
#endif
|
||||
}
|
||||
|
||||
int FTN_STDCALL
|
||||
FTN_SET_AFFINITY( void **mask )
|
||||
{
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#define FTN_SET_LIBRARY kmp_set_library
|
||||
#define FTN_GET_LIBRARY kmp_get_library
|
||||
#define FTN_SET_DEFAULTS kmp_set_defaults
|
||||
#define FTN_SET_DISP_NUM_BUFFERS kmp_set_disp_num_buffers
|
||||
#define FTN_SET_AFFINITY kmp_set_affinity
|
||||
#define FTN_GET_AFFINITY kmp_get_affinity
|
||||
#define FTN_GET_AFFINITY_MAX_PROC kmp_get_affinity_max_proc
|
||||
@@ -152,6 +153,7 @@
|
||||
#define FTN_SET_LIBRARY kmp_set_library_
|
||||
#define FTN_GET_LIBRARY kmp_get_library_
|
||||
#define FTN_SET_DEFAULTS kmp_set_defaults_
|
||||
#define FTN_SET_DISP_NUM_BUFFERS kmp_set_disp_num_buffers_
|
||||
#define FTN_SET_AFFINITY kmp_set_affinity_
|
||||
#define FTN_GET_AFFINITY kmp_get_affinity_
|
||||
#define FTN_GET_AFFINITY_MAX_PROC kmp_get_affinity_max_proc_
|
||||
@@ -270,6 +272,7 @@
|
||||
#define FTN_SET_LIBRARY KMP_SET_LIBRARY
|
||||
#define FTN_GET_LIBRARY KMP_GET_LIBRARY
|
||||
#define FTN_SET_DEFAULTS KMP_SET_DEFAULTS
|
||||
#define FTN_SET_DISP_NUM_BUFFERS KMP_SET_DISP_NUM_BUFFERS
|
||||
#define FTN_SET_AFFINITY KMP_SET_AFFINITY
|
||||
#define FTN_GET_AFFINITY KMP_GET_AFFINITY
|
||||
#define FTN_GET_AFFINITY_MAX_PROC KMP_GET_AFFINITY_MAX_PROC
|
||||
@@ -388,6 +391,7 @@
|
||||
#define FTN_SET_LIBRARY KMP_SET_LIBRARY_
|
||||
#define FTN_GET_LIBRARY KMP_GET_LIBRARY_
|
||||
#define FTN_SET_DEFAULTS KMP_SET_DEFAULTS_
|
||||
#define FTN_SET_DISP_NUM_BUFFERS KMP_SET_DISP_NUM_BUFFERS_
|
||||
#define FTN_SET_AFFINITY KMP_SET_AFFINITY_
|
||||
#define FTN_GET_AFFINITY KMP_GET_AFFINITY_
|
||||
#define FTN_GET_AFFINITY_MAX_PROC KMP_GET_AFFINITY_MAX_PROC_
|
||||
|
||||
@@ -128,6 +128,7 @@ int __kmp_dflt_team_nth_ub = 0;
|
||||
int __kmp_tp_capacity = 0;
|
||||
int __kmp_tp_cached = 0;
|
||||
int __kmp_dflt_nested = FALSE;
|
||||
int __kmp_dispatch_num_buffers = KMP_DFLT_DISP_NUM_BUFF;
|
||||
int __kmp_dflt_max_active_levels = KMP_MAX_ACTIVE_LEVELS_LIMIT; /* max_active_levels limit */
|
||||
#if KMP_NESTED_HOT_TEAMS
|
||||
int __kmp_hot_teams_mode = 0; /* 0 - free extra threads when reduced */
|
||||
|
||||
@@ -489,7 +489,7 @@ __kmp_print_thread_storage_map( kmp_info_t *thr, int gtid )
|
||||
static void
|
||||
__kmp_print_team_storage_map( const char *header, kmp_team_t *team, int team_id, int num_thr )
|
||||
{
|
||||
int num_disp_buff = team->t.t_max_nproc > 1 ? KMP_MAX_DISP_BUF : 2;
|
||||
int num_disp_buff = team->t.t_max_nproc > 1 ? __kmp_dispatch_num_buffers : 2;
|
||||
__kmp_print_storage_map_gtid( -1, team, team + 1, sizeof(kmp_team_t), "%s_%d",
|
||||
header, team_id );
|
||||
|
||||
@@ -2967,7 +2967,7 @@ static void
|
||||
__kmp_allocate_team_arrays(kmp_team_t *team, int max_nth)
|
||||
{
|
||||
int i;
|
||||
int num_disp_buff = max_nth > 1 ? KMP_MAX_DISP_BUF : 2;
|
||||
int num_disp_buff = max_nth > 1 ? __kmp_dispatch_num_buffers : 2;
|
||||
team->t.t_threads = (kmp_info_t**) __kmp_allocate( sizeof(kmp_info_t*) * max_nth );
|
||||
team->t.t_disp_buffer = (dispatch_shared_info_t*)
|
||||
__kmp_allocate( sizeof(dispatch_shared_info_t) * num_disp_buff );
|
||||
@@ -4040,7 +4040,7 @@ __kmp_initialize_info( kmp_info_t *this_thr, kmp_team_t *team, int tid, int gtid
|
||||
* Use team max_nproc since this will never change for the team.
|
||||
*/
|
||||
size_t disp_size = sizeof( dispatch_private_info_t ) *
|
||||
( team->t.t_max_nproc == 1 ? 1 : KMP_MAX_DISP_BUF );
|
||||
( team->t.t_max_nproc == 1 ? 1 : __kmp_dispatch_num_buffers );
|
||||
KD_TRACE( 10, ("__kmp_initialize_info: T#%d max_nproc: %d\n", gtid, team->t.t_max_nproc ) );
|
||||
KMP_ASSERT( dispatch );
|
||||
KMP_DEBUG_ASSERT( team->t.t_dispatch );
|
||||
@@ -4055,7 +4055,7 @@ __kmp_initialize_info( kmp_info_t *this_thr, kmp_team_t *team, int tid, int gtid
|
||||
|
||||
if ( __kmp_storage_map ) {
|
||||
__kmp_print_storage_map_gtid( gtid, &dispatch->th_disp_buffer[ 0 ],
|
||||
&dispatch->th_disp_buffer[ team->t.t_max_nproc == 1 ? 1 : KMP_MAX_DISP_BUF ],
|
||||
&dispatch->th_disp_buffer[ team->t.t_max_nproc == 1 ? 1 : __kmp_dispatch_num_buffers ],
|
||||
disp_size, "th_%d.th_dispatch.th_disp_buffer "
|
||||
"(team_%d.t_dispatch[%d].th_disp_buffer)",
|
||||
gtid, team->t.t_id, gtid );
|
||||
@@ -6997,7 +6997,7 @@ __kmp_internal_fork( ident_t *id, int gtid, kmp_team_t *team )
|
||||
KMP_DEBUG_ASSERT( team->t.t_disp_buffer );
|
||||
if ( team->t.t_max_nproc > 1 ) {
|
||||
int i;
|
||||
for (i = 0; i < KMP_MAX_DISP_BUF; ++i) {
|
||||
for (i = 0; i < __kmp_dispatch_num_buffers; ++i) {
|
||||
team->t.t_disp_buffer[ i ].buffer_index = i;
|
||||
#if OMP_41_ENABLED
|
||||
team->t.t_disp_buffer[i].doacross_buf_idx = i;
|
||||
|
||||
@@ -1197,6 +1197,23 @@ __kmp_stg_print_max_task_priority(kmp_str_buf_t *buffer, char const *name, void
|
||||
} // __kmp_stg_print_max_task_priority
|
||||
#endif // OMP_41_ENABLED
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// KMP_DISP_NUM_BUFFERS
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
static void
|
||||
__kmp_stg_parse_disp_buffers( char const * name, char const * value, void * data ) {
|
||||
if ( TCR_4(__kmp_init_serial) ) {
|
||||
KMP_WARNING( EnvSerialWarn, name );
|
||||
return;
|
||||
} // read value before serial initialization only
|
||||
__kmp_stg_parse_int( name, value, 1, KMP_MAX_NTH, & __kmp_dispatch_num_buffers );
|
||||
} // __kmp_stg_parse_disp_buffers
|
||||
|
||||
static void
|
||||
__kmp_stg_print_disp_buffers( kmp_str_buf_t * buffer, char const * name, void * data ) {
|
||||
__kmp_stg_print_int( buffer, name, __kmp_dispatch_num_buffers );
|
||||
} // __kmp_stg_print_disp_buffers
|
||||
|
||||
#if KMP_NESTED_HOT_TEAMS
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// KMP_HOT_TEAMS_MAX_LEVEL, KMP_HOT_TEAMS_MODE
|
||||
@@ -4646,6 +4663,7 @@ static kmp_setting_t __kmp_stg_table[] = {
|
||||
#endif
|
||||
{ "OMP_THREAD_LIMIT", __kmp_stg_parse_all_threads, __kmp_stg_print_all_threads, NULL, 0, 0 },
|
||||
{ "OMP_WAIT_POLICY", __kmp_stg_parse_wait_policy, __kmp_stg_print_wait_policy, NULL, 0, 0 },
|
||||
{ "KMP_DISP_NUM_BUFFERS", __kmp_stg_parse_disp_buffers, __kmp_stg_print_disp_buffers, NULL, 0, 0 },
|
||||
#if KMP_NESTED_HOT_TEAMS
|
||||
{ "KMP_HOT_TEAMS_MAX_LEVEL", __kmp_stg_parse_hot_teams_level, __kmp_stg_print_hot_teams_level, NULL, 0, 0 },
|
||||
{ "KMP_HOT_TEAMS_MODE", __kmp_stg_parse_hot_teams_mode, __kmp_stg_print_hot_teams_mode, NULL, 0, 0 },
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#define kmp_set_blocktime kmpc_set_blocktime
|
||||
#define kmp_set_library kmpc_set_library
|
||||
#define kmp_set_defaults kmpc_set_defaults
|
||||
#define kmp_set_disp_num_buffers kmpc_set_disp_num_buffers
|
||||
#define kmp_malloc kmpc_malloc
|
||||
#define kmp_aligned_malloc kmpc_aligned_malloc
|
||||
#define kmp_calloc kmpc_calloc
|
||||
@@ -100,6 +101,7 @@ void kmp_set_stacksize_s( size_t arg ) { i; __kmps_set_stacksize( arg ); }
|
||||
void kmp_set_blocktime( omp_int_t arg ) { i; __kmps_set_blocktime( arg ); }
|
||||
void kmp_set_library( omp_int_t arg ) { i; __kmps_set_library( arg ); }
|
||||
void kmp_set_defaults( char const * str ) { i; }
|
||||
void kmp_set_disp_num_buffers( omp_int_t arg ) { i; }
|
||||
|
||||
/* KMP memory management functions. */
|
||||
void * kmp_malloc( size_t size ) { i; return malloc( size ); }
|
||||
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
// RUN: %libomp-compile && env KMP_DISP_NUM_BUFFERS=0 %libomp-run
|
||||
// RUN: env KMP_DISP_NUM_BUFFERS=1 %libomp-run && env KMP_DISP_NUM_BUFFERS=3 %libomp-run
|
||||
// RUN: env KMP_DISP_NUM_BUFFERS=4 %libomp-run && env KMP_DISP_NUM_BUFFERS=7 %libomp-run
|
||||
// RUN: %libomp-compile -DMY_SCHEDULE=guided && env KMP_DISP_NUM_BUFFERS=1 %libomp-run
|
||||
// RUN: env KMP_DISP_NUM_BUFFERS=3 %libomp-run && env KMP_DISP_NUM_BUFFERS=4 %libomp-run
|
||||
// RUN: env KMP_DISP_NUM_BUFFERS=7 %libomp-run
|
||||
#include <stdio.h>
|
||||
#include <omp.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include "omp_testsuite.h"
|
||||
|
||||
#define INCR 7
|
||||
#define MY_MAX 200
|
||||
#define MY_MIN -200
|
||||
#define NUM_LOOPS 100
|
||||
#ifndef MY_SCHEDULE
|
||||
# define MY_SCHEDULE dynamic
|
||||
#endif
|
||||
|
||||
int a, b, a_known_value, b_known_value;
|
||||
|
||||
int test_kmp_set_disp_num_buffers()
|
||||
{
|
||||
int success = 1;
|
||||
a = 0;
|
||||
b = 0;
|
||||
// run many small dynamic loops to stress the dispatch buffer system
|
||||
#pragma omp parallel
|
||||
{
|
||||
int i,j;
|
||||
for (j = 0; j < NUM_LOOPS; j++) {
|
||||
#pragma omp for schedule(MY_SCHEDULE) nowait
|
||||
for (i = MY_MIN; i < MY_MAX; i+=INCR) {
|
||||
#pragma omp atomic
|
||||
a++;
|
||||
}
|
||||
#pragma omp for schedule(MY_SCHEDULE) nowait
|
||||
for (i = MY_MAX; i >= MY_MIN; i-=INCR) {
|
||||
#pragma omp atomic
|
||||
b++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// detect failure
|
||||
if (a != a_known_value || b != b_known_value) {
|
||||
success = 0;
|
||||
printf("a = %d (should be %d), b = %d (should be %d)\n", a, a_known_value,
|
||||
b, b_known_value);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int i,j;
|
||||
int num_failed=0;
|
||||
|
||||
// figure out the known values to compare with calculated result
|
||||
a_known_value = 0;
|
||||
b_known_value = 0;
|
||||
|
||||
for (j = 0; j < NUM_LOOPS; j++) {
|
||||
for (i = MY_MIN; i < MY_MAX; i+=INCR)
|
||||
a_known_value++;
|
||||
for (i = MY_MAX; i >= MY_MIN; i-=INCR)
|
||||
b_known_value++;
|
||||
}
|
||||
|
||||
for(i = 0; i < REPETITIONS; i++) {
|
||||
if(!test_kmp_set_disp_num_buffers()) {
|
||||
num_failed++;
|
||||
}
|
||||
}
|
||||
return num_failed;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
// RUN: %libomp-compile && %libomp-run 7
|
||||
// RUN: %libomp-run 0 && %libomp-run -1
|
||||
// RUN: %libomp-run 1 && %libomp-run 2 && %libomp-run 5
|
||||
// RUN: %libomp-compile -DMY_SCHEDULE=guided && %libomp-run 7
|
||||
// RUN: %libomp-run 1 && %libomp-run 2 && %libomp-run 5
|
||||
#include <stdio.h>
|
||||
#include <omp.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include "omp_testsuite.h"
|
||||
|
||||
#define INCR 7
|
||||
#define MY_MAX 200
|
||||
#define MY_MIN -200
|
||||
#ifndef MY_SCHEDULE
|
||||
# define MY_SCHEDULE dynamic
|
||||
#endif
|
||||
|
||||
int num_disp_buffers, num_loops;
|
||||
int a, b, a_known_value, b_known_value;
|
||||
|
||||
int test_kmp_set_disp_num_buffers()
|
||||
{
|
||||
int success = 1;
|
||||
a = 0;
|
||||
b = 0;
|
||||
// run many small dynamic loops to stress the dispatch buffer system
|
||||
#pragma omp parallel
|
||||
{
|
||||
int i,j;
|
||||
for (j = 0; j < num_loops; j++) {
|
||||
#pragma omp for schedule(MY_SCHEDULE) nowait
|
||||
for (i = MY_MIN; i < MY_MAX; i+=INCR) {
|
||||
#pragma omp atomic
|
||||
a++;
|
||||
}
|
||||
#pragma omp for schedule(MY_SCHEDULE) nowait
|
||||
for (i = MY_MAX; i >= MY_MIN; i-=INCR) {
|
||||
#pragma omp atomic
|
||||
b++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// detect failure
|
||||
if (a != a_known_value || b != b_known_value) {
|
||||
success = 0;
|
||||
printf("a = %d (should be %d), b = %d (should be %d)\n", a, a_known_value,
|
||||
b, b_known_value);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int i,j;
|
||||
int num_failed=0;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: %s num_disp_buffers\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// set the number of dispatch buffers
|
||||
num_disp_buffers = atoi(argv[1]);
|
||||
kmp_set_disp_num_buffers(num_disp_buffers);
|
||||
|
||||
// figure out the known values to compare with calculated result
|
||||
a_known_value = 0;
|
||||
b_known_value = 0;
|
||||
|
||||
// if specified to use bad num_disp_buffers set num_loops
|
||||
// to something reasonable
|
||||
if (num_disp_buffers <= 0)
|
||||
num_loops = 10;
|
||||
else
|
||||
num_loops = num_disp_buffers*10;
|
||||
|
||||
for (j = 0; j < num_loops; j++) {
|
||||
for (i = MY_MIN; i < MY_MAX; i+=INCR)
|
||||
a_known_value++;
|
||||
for (i = MY_MAX; i >= MY_MIN; i-=INCR)
|
||||
b_known_value++;
|
||||
}
|
||||
|
||||
for(i = 0; i < REPETITIONS; i++) {
|
||||
if(!test_kmp_set_disp_num_buffers()) {
|
||||
num_failed++;
|
||||
}
|
||||
}
|
||||
return num_failed;
|
||||
}
|
||||
Reference in New Issue
Block a user