Add memoryPerNode option

master
Christopher J. Morrone 2012-01-08 18:41:30 -08:00
parent 5ea51638df
commit 4084e14d02
5 changed files with 113 additions and 16 deletions

View File

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

View File

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

View File

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

View File

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

View File

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