Take memory from envirnoment variables; document those.

This commit is contained in:
Thomas Koenig 2021-10-04 22:34:53 +02:00
parent c92ee4037c
commit 8df87c9e2c
5 changed files with 94 additions and 14 deletions

View File

@ -608,6 +608,8 @@ Malformed environment variables are silently ignored.
* GFORTRAN_ERROR_BACKTRACE:: Show backtrace on run-time errors
* GFORTRAN_FORMATTED_BUFFER_SIZE:: Buffer size for formatted files
* GFORTRAN_UNFORMATTED_BUFFER_SIZE:: Buffer size for unformatted files
* GFORTRAN_NUM_IMAGES:: Number of images to for -fcoarray=shared
* GFORTRAN_SHARED_MEMORY_SIZE:: Memory for shared-memory coarrays
@end menu
@node TMPDIR
@ -793,6 +795,35 @@ The @env{GFORTRAN_UNFORMATTED_BUFFER_SIZE} environment variable
specifies buffer size in bytes to be used for unformatted output.
The default value is 131072.
@node GFORTRAN_NUM_IMAGES
@section @env{GFORTRAN_NUM_IMAGES}---Set number of images for shared-memory coarrays
The @env{GFORTRAN_NUM_IMAGES} environment variable specifies the number
of images to be run for shared-memory coarrays, as an integer. The default
value is the number of CPUs on the system.
@node GFORTRAN_SHARED_MEMORY_SIZE
@section @env{GFORTRAN_SHARED_MEMORY_SIZE}---Set size for shared-memory coarrays
The @env{GFORTRAN_SHARED_MEMORY_SIZE} environment variable specifies
the size of the shared memory block to be allocated for shared
coarrays. It is safe on Linux and Darwin to make this larger than
needed. When specifying this value, keep in mind that part of the space
will not be available to the user program because of overhead.
The format is an integer, optionally followed by @code{k} or @code{K}
for a unit of kilobytes, @code{m} or @code{M} for a unit of megabytes
and @code{g} or @code{G} for a unit of gitabytes.
For example, if the size of all coarrays is known to be smaller than
50 megabyte, the syntax could be
@smallexample
$ GFORTRAN_SHARED_MEMORY_SIZE=80M ./a.out
@end smallexample
The default is 256 kilobyte for 32-bit systems and 256 gigabyte for
64-bit systems.
@c =====================================================================
@c PART II: LANGUAGE REFERENCE
@c =====================================================================

View File

@ -188,7 +188,7 @@ and warnings}.
-fbounds-check -ftail-call-workaround -ftail-call-workaround=@var{n} @gol
-fcheck-array-temporaries @gol
-fcheck=@var{<all|array-temps|bits|bounds|do|mem|pointer|recursion>} @gol
-fcoarray=@var{<none|single|lib>} -fexternal-blas -ff2c @gol
-fcoarray=@var{<none|single|lib|shared>} -fexternal-blas -ff2c @gol
-ffrontend-loop-interchange -ffrontend-optimize @gol
-finit-character=@var{n} -finit-integer=@var{n} -finit-local-zero @gol
-finit-derived -finit-logical=@var{<true|false>} @gol
@ -1607,6 +1607,13 @@ Single-image mode, i.e. @code{num_images()} is always one.
@item @samp{lib}
Library-based coarray parallelization; a suitable GNU Fortran coarray
library needs to be linked.
@item @samp{shared}
This enables an experimental shared-memory implementation of
coarrays. Expect bugs and incomplete implementation. Currently,
this depends on POSIX shared mutexes, so this option is not supported
on systems which do not have them. There is no Windows implementation
at the moment.
@end table

View File

@ -35,6 +35,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include <string.h>
#define GFORTRAN_ENV_NUM_IMAGES "GFORTRAN_NUM_IMAGES"
#define GFORTRAN_ENV_SHARED_MEMORY_SIZE "GFORTRAN_SHARED_MEMORY_SIZE"
nca_local_data *local = NULL;
@ -55,6 +56,54 @@ get_environ_image_num (void)
return nimages;
}
/* Get the amount of memory for the shared memory block. This is picked from
an environment variable. If that is not there, pick a reasonable default.
Note that on a 64-bit system which allows overcommit, there is no penalty in
reserving a large space and then not using it. */
static size_t
get_memory_size (void)
{
char *e;
size_t sz = 0;
e = getenv (GFORTRAN_ENV_SHARED_MEMORY_SIZE);
if (e)
{
char *num, suffix;
int rv;
rv = sscanf (e, "%zu%1s",&sz, &suffix);
if (rv == 2)
{
switch (suffix)
{
case 'k':
case 'K':
sz *= ((size_t) 1) << 10;
break;
case 'm':
case 'M':
sz *= ((size_t) 1) << 20;
break;
case 'g':
case 'G':
sz *= ((size_t) 1) << 30;
break;
default:
sz = 0;
}
}
}
if (sz == 0)
{
/* Use 256 MB for 32-bit systems and 256 GB for 64-bit systems. */
if (sizeof (size_t) == 4)
sz = ((size_t) 1) << 28;
else
sz = ((size_t) 1) << 38;
}
return sz;
}
/* Get a master. */
static master *
@ -79,6 +128,8 @@ get_master (void)
void
ensure_initialization (void)
{
size_t shmem_size;
if (local)
return;
@ -86,8 +137,9 @@ ensure_initialization (void)
// that point? Maybe use
// mmap(MAP_ANON) instead
pagesize = sysconf (_SC_PAGE_SIZE);
shmem_size = round_to_pagesize (get_memory_size());
local->total_num_images = get_environ_image_num ();
shared_memory_init (&local->sm);
shared_memory_init (&local->sm, shmem_size);
shared_memory_prepare (&local->sm);
if (this_image.m == NULL) /* A bit of a hack, but we
need the master early. */

View File

@ -186,21 +186,11 @@ shared_memory_prepare (shared_memory_act **pmem)
shared memory is stored at the beginning. */
void
shared_memory_init (shared_memory_act **pmem)
shared_memory_init (shared_memory_act **pmem, size_t initial_size)
{
shared_memory_act *mem;
int fd;
/* Darwin does not appear to be able to grow shared memory segments. Choose
256 GB; that will likely be enough. If not, the ftruncate will fail
noisily. */
#ifdef __APPLE__
size_t initial_size = ((size_t) 1) << 38;
#else
size_t initial_size = round_to_pagesize (sizeof (global_shared_memory_meta));
#endif
mem = malloc (get_shared_memory_act_size (1));
fd = get_shmem_fd ();

View File

@ -53,7 +53,7 @@ typedef struct shared_mem_ptr
ssize_t offset;
} shared_mem_ptr;
void shared_memory_init (shared_memory *);
void shared_memory_init (shared_memory *, size_t);
internal_proto (shared_memory_init);
void shared_memory_prepare (shared_memory *);