Add memoryPerNode option
parent
5ea51638df
commit
4084e14d02
|
@ -142,6 +142,7 @@ These options are to be used on the command line. E.g., 'IOR -a POSIX -b 4K'.
|
|||
-k keepFile -- don't remove the test file(s) on program exit
|
||||
-K keepFileWithError -- keep error-filled file(s) after data-checking
|
||||
-l storeFileOffset -- use file offset as stored signature
|
||||
-M S memoryPerNode -- hog memory on the node
|
||||
-m multiFile -- use number of reps (-i) for multiple file count
|
||||
-n noFill -- no fill in HDF5 file creation
|
||||
-N N numTasks -- number of tasks that should participate in the test
|
||||
|
@ -304,6 +305,15 @@ GENERAL:
|
|||
file [0=FALSE]
|
||||
NOTE: this will affect performance measurements
|
||||
|
||||
* memoryPerNode - Allocate memory on each node to simulate real
|
||||
application memory usage. Accepts a percentage of
|
||||
node memory (e.g. "50%") on machines that support
|
||||
sysconf(_SC_PHYS_PAGES) or a size. Allocation will
|
||||
be split between tasks that share the node.
|
||||
|
||||
* memoryPerTask - Allocate secified amount of memory per task to
|
||||
simulate real application memory usage.
|
||||
|
||||
* maxTimeDuration - max time in minutes to run tests [0]
|
||||
NOTES: * setting this to zero (0) unsets this option
|
||||
* this option allows the current read/write
|
||||
|
|
51
src/ior.c
51
src/ior.c
|
@ -68,7 +68,6 @@ static char *CheckTorF(char *);
|
|||
static size_t CompareBuffers(void *, void *, size_t,
|
||||
IOR_offset_t, IOR_param_t *, int);
|
||||
static int CountErrors(IOR_param_t *, int, int);
|
||||
static int CountTasksPerNode(int, MPI_Comm);
|
||||
static void *CreateBuffer(size_t);
|
||||
static void DelaySecs(int);
|
||||
static void DestroyTests(IOR_test_t *tests_head);
|
||||
|
@ -89,8 +88,6 @@ static void PrintHeader(int argc, char **argv);
|
|||
static void ReadCheck(void *, void *, void *, void *, IOR_param_t *,
|
||||
IOR_offset_t, IOR_offset_t, IOR_offset_t *,
|
||||
IOR_offset_t *, int, int *);
|
||||
static void ReduceIterResults(IOR_test_t *test, double **timer,
|
||||
int rep, int access);
|
||||
static void RemoveFile(char *, int, IOR_param_t *);
|
||||
static void SetupXferBuffers(void **, void **, void **,
|
||||
IOR_param_t *, int, int);
|
||||
|
@ -1542,10 +1539,14 @@ static void ShowSetup(IOR_param_t *params)
|
|||
}
|
||||
fprintf(stdout, "\tclients = %d (%d per node)\n",
|
||||
params->numTasks, params->tasksPerNode);
|
||||
fprintf(stdout, "\tmemoryPerTask = %s\n",
|
||||
HumanReadable(params->memoryPerTask, BASE_TWO));
|
||||
fprintf(stdout, "\trepetitions = %d\n", params->repetitions);
|
||||
fprintf(stdout, "\txfersize = %s\n",
|
||||
if (params->memoryPerTask != 0)
|
||||
printf("\tmemoryPerTask = %s\n",
|
||||
HumanReadable(params->memoryPerTask, BASE_TWO));
|
||||
if (params->memoryPerNode != 0)
|
||||
printf("\tmemoryPerNode = %s\n",
|
||||
HumanReadable(params->memoryPerNode, BASE_TWO));
|
||||
printf("\trepetitions = %d\n", params->repetitions);
|
||||
printf("\txfersize = %s\n",
|
||||
HumanReadable(params->transferSize, BASE_TWO));
|
||||
fprintf(stdout, "\tblocksize = %s\n",
|
||||
HumanReadable(params->blockSize, BASE_TWO));
|
||||
|
@ -1588,6 +1589,7 @@ static void ShowTest(IOR_param_t * test)
|
|||
fprintf(stdout, "\t%s=%s\n", "options", test->options);
|
||||
fprintf(stdout, "\t%s=%d\n", "nodes", test->nodes);
|
||||
fprintf(stdout, "\t%s=%lu\n", "memoryPerTask", (unsigned long) test->memoryPerTask);
|
||||
fprintf(stdout, "\t%s=%lu\n", "memoryPerNode", (unsigned long) test->memoryPerNode);
|
||||
fprintf(stdout, "\t%s=%d\n", "tasksPerNode", tasksPerNode);
|
||||
fprintf(stdout, "\t%s=%d\n", "repetitions", test->repetitions);
|
||||
fprintf(stdout, "\t%s=%d\n", "multiFile", test->multiFile);
|
||||
|
@ -1865,7 +1867,7 @@ static void *malloc_and_touch(size_t size)
|
|||
|
||||
buf = (char *)malloc(size);
|
||||
if (buf == NULL)
|
||||
ERR("malloc failed");
|
||||
return NULL;
|
||||
|
||||
for (ptr = buf; ptr < buf+size; ptr += page_size) {
|
||||
*ptr = (char)1;
|
||||
|
@ -1874,6 +1876,35 @@ static void *malloc_and_touch(size_t size)
|
|||
return (void *)buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* hog some memory as a rough simulation of a real application's memory use
|
||||
*/
|
||||
static void *HogMemory(IOR_param_t *params)
|
||||
{
|
||||
size_t size;
|
||||
void *buf;
|
||||
|
||||
if (params->memoryPerTask != 0) {
|
||||
size = params->memoryPerTask;
|
||||
} else if (params->memoryPerNode != 0) {
|
||||
if (verbose >= VERBOSE_3)
|
||||
fprintf(stderr, "This node hogging %ld bytes of memory\n",
|
||||
params->memoryPerNode);
|
||||
size = params->memoryPerNode / params->tasksPerNode;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (verbose >= VERBOSE_3)
|
||||
fprintf(stderr, "This task hogging %ld bytes of memory\n", size);
|
||||
|
||||
buf = malloc_and_touch(size);
|
||||
if (buf == NULL)
|
||||
ERR("malloc of simulated applciation buffer failed");
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Using the test parameters, run iteration(s) of single test.
|
||||
*/
|
||||
|
@ -1942,9 +1973,7 @@ static void TestIoSys(IOR_test_t *test)
|
|||
if (rank == 0 && verbose >= VERBOSE_0)
|
||||
ShowSetup(params);
|
||||
|
||||
/* hog some memory as a rough simulation of a real application's
|
||||
memory use */
|
||||
hog_buf = malloc_and_touch(params->memoryPerTask);
|
||||
hog_buf = HogMemory(params);
|
||||
|
||||
startTime = GetTimeStamp();
|
||||
maxTimeDuration = params->maxTimeDuration * 60; /* convert to seconds */
|
||||
|
|
|
@ -95,7 +95,8 @@ typedef struct
|
|||
int randomSeed; /* random seed for write/read check */
|
||||
int randomOffset; /* access is to random offsets */
|
||||
MPI_Comm testComm; /* MPI communicator */
|
||||
size_t memoryPerTask; /* additional memory used per task */
|
||||
size_t memoryPerTask; /* additional memory used per task */
|
||||
size_t memoryPerNode; /* additional memory used per node */
|
||||
|
||||
/* POSIX variables */
|
||||
int singleXferAttempt; /* do not retry transfer if incomplete */
|
||||
|
|
|
@ -21,10 +21,63 @@
|
|||
#include "ior.h"
|
||||
#include "aiori.h"
|
||||
#include "parse_options.h"
|
||||
#include "utilities.h"
|
||||
|
||||
IOR_param_t initialTestParams;
|
||||
|
||||
/*
|
||||
* Takes a string of the form 64, 8m, 128k, 4g, etc. and converts to bytes.
|
||||
*/
|
||||
static IOR_offset_t StringToBytes(char *size_str)
|
||||
{
|
||||
IOR_offset_t size = 0;
|
||||
char range;
|
||||
int rc;
|
||||
|
||||
rc = sscanf(size_str, " %lld %c ", &size, &range);
|
||||
if (rc == 2) {
|
||||
switch ((int)range) {
|
||||
case 'k':
|
||||
case 'K':
|
||||
size <<= 10;
|
||||
break;
|
||||
case 'm':
|
||||
case 'M':
|
||||
size <<= 20;
|
||||
break;
|
||||
case 'g':
|
||||
case 'G':
|
||||
size <<= 30;
|
||||
break;
|
||||
}
|
||||
} else if (rc == 0) {
|
||||
size = -1;
|
||||
}
|
||||
return (size);
|
||||
}
|
||||
|
||||
static size_t NodeMemoryStringToBytes(char *size_str)
|
||||
{
|
||||
int percent;
|
||||
int rc;
|
||||
long page_size;
|
||||
long num_pages;
|
||||
long long mem;
|
||||
|
||||
rc = sscanf(size_str, " %d %% ", &percent);
|
||||
if (rc == 0)
|
||||
return (size_t)StringToBytes(size_str);
|
||||
if (percent > 100 || percent < 0)
|
||||
ERR("percentage must be between 0 and 100");
|
||||
|
||||
page_size = sysconf(_SC_PAGESIZE);
|
||||
num_pages = sysconf(_SC_PHYS_PAGES);
|
||||
if (num_pages == -1)
|
||||
ERR("sysconf(_SC_PHYS_PAGES) is not supported");
|
||||
mem = page_size * num_pages;
|
||||
|
||||
return mem / 100 * percent;
|
||||
}
|
||||
|
||||
static void RecalculateExpectedFileSize(IOR_param_t *params)
|
||||
{
|
||||
params->expectedAggFileSize =
|
||||
|
@ -176,6 +229,10 @@ void DecodeDirective(char *line, IOR_param_t *params)
|
|||
params->randomOffset = atoi(value);
|
||||
} else if (strcasecmp(option, "memoryPerTask") == 0) {
|
||||
params->memoryPerTask = StringToBytes(value);
|
||||
params->memoryPerNode = 0;
|
||||
} else if (strcasecmp(option, "memoryPerNode") == 0) {
|
||||
params->memoryPerNode = NodeMemoryStringToBytes(value);
|
||||
params->memoryPerTask = 0;
|
||||
} else if (strcasecmp(option, "lustrestripecount") == 0) {
|
||||
#ifndef HAVE_LUSTRE_LUSTRE_USER_H
|
||||
ERR("ior was not compiled with Lustre support");
|
||||
|
@ -340,7 +397,7 @@ IOR_test_t *ReadConfigScript(char *scriptName)
|
|||
IOR_test_t *ParseCommandLine(int argc, char **argv)
|
||||
{
|
||||
static const char *opts =
|
||||
"A:a:b:BcCQ:ZX:d:D:YeEf:FgG:hHi:j:J:IkKlmnN:o:O:pPqrRs:St:T:uU:vVwWxz";
|
||||
"A:a:b:BcCQ:ZX:d:D:YeEf:FgG:hHi:j:J:IkKlmM:nN:o:O:pPqrRs:St:T:uU:vVwWxz";
|
||||
int c, i;
|
||||
static IOR_test_t *tests = NULL;
|
||||
|
||||
|
@ -438,7 +495,8 @@ IOR_test_t *ParseCommandLine(int argc, char **argv)
|
|||
initialTestParams.storeFileOffset = TRUE;
|
||||
break;
|
||||
case 'M':
|
||||
initialTestParams.memoryPerTask = StringToBytes(optarg);
|
||||
initialTestParams.memoryPerNode =
|
||||
NodeMemoryStringToBytes(optarg);
|
||||
break;
|
||||
case 'm':
|
||||
initialTestParams.multiFile = TRUE;
|
||||
|
|
|
@ -21,7 +21,6 @@ void OutputToRoot(int, MPI_Comm, char *);
|
|||
int Regex(char *, char *);
|
||||
void ShowFileSystemSize(char *);
|
||||
void DumpBuffer(void *, size_t);
|
||||
IOR_offset_t StringToBytes(char *);
|
||||
void SeedRandGen(MPI_Comm);
|
||||
#if USE_UNDOC_OPT
|
||||
void CorruptFile(char *, IOR_param_t *, int, int);
|
||||
|
|
Loading…
Reference in New Issue