Noam Bernstein <noam.bernst...@nrl.navy.mil> writes:

> Can anyone shed some light on where the _virtual_ memory limit comes from?

Perhaps it comes from a VSizeFactor setting in slurm.conf:

       VSizeFactor
              Memory specifications in job requests apply to real memory size 
(also known as
              resident set size). It is possible to enforce virtual memory 
limits  for  both
              jobs  and  job  steps  by  limiting their virtual memory to some 
percentage of
              their real memory allocation. The VSizeFactor parameter specifies 
the job's or
              job  step's virtual memory limit as a percentage of its real 
memory limit. For
              example, if a job's real memory limit is 500MB and VSizeFactor is 
set  to  101
              then  the  job  will be killed if its real memory exceeds 500MB 
or its virtual
              memory exceeds 505MB (101 percent of the  real  memory  limit).   
The  default
              value  is  0,  which disables enforcement of virtual memory 
limits.  The value
              may not exceed 65533 percent.

> 1. If I define DefMemPerCPU in the partition line, and the job doesn't request
> anything else, what memory measure should expect this to be the limit
> on? RSS?

Yes, RSS.

To test our memory settings, we often use a small program like the
attached C program.  It first allocates memory (to test vmem limit),
then fills it with values (to test rss limit), and finally re-reads the
memory (to check for swapping).

It is built like this

    gcc -DMB=$((30*1024)) -o malloc_30 malloc.c

for allocating 30 GiB.  (Yes, I could have made the size a command line
parameter, but I am lazy. :)

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

#define BYTES (MB * 1024 * 1024ul)
#define SEGMENT_SIZE 1024       /* num bytes to set at a time.
                                   Must divide BYTES */
#define SLEEP 10

int main () {
  char *large;
  int single, read_size = sizeof(int);
  unsigned long i;

  large = (char *)malloc(BYTES*sizeof(char));
  if (large != NULL) {
    printf("Malloc: allocated %lu B\n", BYTES);
  } else {
    printf("Malloc: Aaargh! Crash and burn...\n");
    exit(1);
  }
  fflush(NULL);

  printf("Malloc: sleeping for %d seconds...\n", SLEEP);
  fflush(NULL);
  sleep(SLEEP);

  printf("Malloc: Starting to fill...\n");
  fflush(NULL);
  for (i = 0; i < BYTES; i += SEGMENT_SIZE) {
    memset(large + i, 42, SEGMENT_SIZE);
  }
  printf("Malloc: Filled %lu bytes\n", i);
  fflush(NULL);

  printf("Malloc: sleeping for %d seconds...\n", SLEEP);
  fflush(NULL);
  sleep(SLEEP);

  printf("Malloc: Starting to read...\n");
  fflush(NULL);
  for (i = 0; i < BYTES; i += read_size) {
    single = *(int*)(large + i);
    //single = *(large + i);
  }
  printf("Malloc: Read %lu bytes\n", i);
  fflush(NULL);

  printf("Malloc: sleeping for %d seconds...\n", SLEEP);
  fflush(NULL);
  sleep(SLEEP);

  printf("Malloc: done.\n");
  fflush(NULL);

  return 0;
}
-- 
Regards,
Bjørn-Helge Mevik, dr. scient,
Department for Research Computing, University of Oslo

Attachment: signature.asc
Description: PGP signature

Reply via email to