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 keepFile -- don't remove the test file(s) on program exit
|
||||||
-K keepFileWithError -- keep error-filled file(s) after data-checking
|
-K keepFileWithError -- keep error-filled file(s) after data-checking
|
||||||
-l storeFileOffset -- use file offset as stored signature
|
-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
|
-m multiFile -- use number of reps (-i) for multiple file count
|
||||||
-n noFill -- no fill in HDF5 file creation
|
-n noFill -- no fill in HDF5 file creation
|
||||||
-N N numTasks -- number of tasks that should participate in the test
|
-N N numTasks -- number of tasks that should participate in the test
|
||||||
|
@ -304,6 +305,15 @@ GENERAL:
|
||||||
file [0=FALSE]
|
file [0=FALSE]
|
||||||
NOTE: this will affect performance measurements
|
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]
|
* maxTimeDuration - max time in minutes to run tests [0]
|
||||||
NOTES: * setting this to zero (0) unsets this option
|
NOTES: * setting this to zero (0) unsets this option
|
||||||
* this option allows the current read/write
|
* 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,
|
static size_t CompareBuffers(void *, void *, size_t,
|
||||||
IOR_offset_t, IOR_param_t *, int);
|
IOR_offset_t, IOR_param_t *, int);
|
||||||
static int CountErrors(IOR_param_t *, int, int);
|
static int CountErrors(IOR_param_t *, int, int);
|
||||||
static int CountTasksPerNode(int, MPI_Comm);
|
|
||||||
static void *CreateBuffer(size_t);
|
static void *CreateBuffer(size_t);
|
||||||
static void DelaySecs(int);
|
static void DelaySecs(int);
|
||||||
static void DestroyTests(IOR_test_t *tests_head);
|
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 *,
|
static void ReadCheck(void *, void *, void *, void *, IOR_param_t *,
|
||||||
IOR_offset_t, IOR_offset_t, IOR_offset_t *,
|
IOR_offset_t, IOR_offset_t, IOR_offset_t *,
|
||||||
IOR_offset_t *, int, int *);
|
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 RemoveFile(char *, int, IOR_param_t *);
|
||||||
static void SetupXferBuffers(void **, void **, void **,
|
static void SetupXferBuffers(void **, void **, void **,
|
||||||
IOR_param_t *, int, int);
|
IOR_param_t *, int, int);
|
||||||
|
@ -1542,10 +1539,14 @@ static void ShowSetup(IOR_param_t *params)
|
||||||
}
|
}
|
||||||
fprintf(stdout, "\tclients = %d (%d per node)\n",
|
fprintf(stdout, "\tclients = %d (%d per node)\n",
|
||||||
params->numTasks, params->tasksPerNode);
|
params->numTasks, params->tasksPerNode);
|
||||||
fprintf(stdout, "\tmemoryPerTask = %s\n",
|
if (params->memoryPerTask != 0)
|
||||||
HumanReadable(params->memoryPerTask, BASE_TWO));
|
printf("\tmemoryPerTask = %s\n",
|
||||||
fprintf(stdout, "\trepetitions = %d\n", params->repetitions);
|
HumanReadable(params->memoryPerTask, BASE_TWO));
|
||||||
fprintf(stdout, "\txfersize = %s\n",
|
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));
|
HumanReadable(params->transferSize, BASE_TWO));
|
||||||
fprintf(stdout, "\tblocksize = %s\n",
|
fprintf(stdout, "\tblocksize = %s\n",
|
||||||
HumanReadable(params->blockSize, BASE_TWO));
|
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=%s\n", "options", test->options);
|
||||||
fprintf(stdout, "\t%s=%d\n", "nodes", test->nodes);
|
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", "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", "tasksPerNode", tasksPerNode);
|
||||||
fprintf(stdout, "\t%s=%d\n", "repetitions", test->repetitions);
|
fprintf(stdout, "\t%s=%d\n", "repetitions", test->repetitions);
|
||||||
fprintf(stdout, "\t%s=%d\n", "multiFile", test->multiFile);
|
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);
|
buf = (char *)malloc(size);
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
ERR("malloc failed");
|
return NULL;
|
||||||
|
|
||||||
for (ptr = buf; ptr < buf+size; ptr += page_size) {
|
for (ptr = buf; ptr < buf+size; ptr += page_size) {
|
||||||
*ptr = (char)1;
|
*ptr = (char)1;
|
||||||
|
@ -1874,6 +1876,35 @@ static void *malloc_and_touch(size_t size)
|
||||||
return (void *)buf;
|
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.
|
* 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)
|
if (rank == 0 && verbose >= VERBOSE_0)
|
||||||
ShowSetup(params);
|
ShowSetup(params);
|
||||||
|
|
||||||
/* hog some memory as a rough simulation of a real application's
|
hog_buf = HogMemory(params);
|
||||||
memory use */
|
|
||||||
hog_buf = malloc_and_touch(params->memoryPerTask);
|
|
||||||
|
|
||||||
startTime = GetTimeStamp();
|
startTime = GetTimeStamp();
|
||||||
maxTimeDuration = params->maxTimeDuration * 60; /* convert to seconds */
|
maxTimeDuration = params->maxTimeDuration * 60; /* convert to seconds */
|
||||||
|
|
|
@ -95,7 +95,8 @@ typedef struct
|
||||||
int randomSeed; /* random seed for write/read check */
|
int randomSeed; /* random seed for write/read check */
|
||||||
int randomOffset; /* access is to random offsets */
|
int randomOffset; /* access is to random offsets */
|
||||||
MPI_Comm testComm; /* MPI communicator */
|
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 */
|
/* POSIX variables */
|
||||||
int singleXferAttempt; /* do not retry transfer if incomplete */
|
int singleXferAttempt; /* do not retry transfer if incomplete */
|
||||||
|
|
|
@ -21,10 +21,63 @@
|
||||||
#include "ior.h"
|
#include "ior.h"
|
||||||
#include "aiori.h"
|
#include "aiori.h"
|
||||||
#include "parse_options.h"
|
#include "parse_options.h"
|
||||||
#include "utilities.h"
|
|
||||||
|
|
||||||
IOR_param_t initialTestParams;
|
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)
|
static void RecalculateExpectedFileSize(IOR_param_t *params)
|
||||||
{
|
{
|
||||||
params->expectedAggFileSize =
|
params->expectedAggFileSize =
|
||||||
|
@ -176,6 +229,10 @@ void DecodeDirective(char *line, IOR_param_t *params)
|
||||||
params->randomOffset = atoi(value);
|
params->randomOffset = atoi(value);
|
||||||
} else if (strcasecmp(option, "memoryPerTask") == 0) {
|
} else if (strcasecmp(option, "memoryPerTask") == 0) {
|
||||||
params->memoryPerTask = StringToBytes(value);
|
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) {
|
} else if (strcasecmp(option, "lustrestripecount") == 0) {
|
||||||
#ifndef HAVE_LUSTRE_LUSTRE_USER_H
|
#ifndef HAVE_LUSTRE_LUSTRE_USER_H
|
||||||
ERR("ior was not compiled with Lustre support");
|
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)
|
IOR_test_t *ParseCommandLine(int argc, char **argv)
|
||||||
{
|
{
|
||||||
static const char *opts =
|
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;
|
int c, i;
|
||||||
static IOR_test_t *tests = NULL;
|
static IOR_test_t *tests = NULL;
|
||||||
|
|
||||||
|
@ -438,7 +495,8 @@ IOR_test_t *ParseCommandLine(int argc, char **argv)
|
||||||
initialTestParams.storeFileOffset = TRUE;
|
initialTestParams.storeFileOffset = TRUE;
|
||||||
break;
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
initialTestParams.memoryPerTask = StringToBytes(optarg);
|
initialTestParams.memoryPerNode =
|
||||||
|
NodeMemoryStringToBytes(optarg);
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
initialTestParams.multiFile = TRUE;
|
initialTestParams.multiFile = TRUE;
|
||||||
|
|
|
@ -21,7 +21,6 @@ void OutputToRoot(int, MPI_Comm, char *);
|
||||||
int Regex(char *, char *);
|
int Regex(char *, char *);
|
||||||
void ShowFileSystemSize(char *);
|
void ShowFileSystemSize(char *);
|
||||||
void DumpBuffer(void *, size_t);
|
void DumpBuffer(void *, size_t);
|
||||||
IOR_offset_t StringToBytes(char *);
|
|
||||||
void SeedRandGen(MPI_Comm);
|
void SeedRandGen(MPI_Comm);
|
||||||
#if USE_UNDOC_OPT
|
#if USE_UNDOC_OPT
|
||||||
void CorruptFile(char *, IOR_param_t *, int, int);
|
void CorruptFile(char *, IOR_param_t *, int, int);
|
||||||
|
|
Loading…
Reference in New Issue