The instructions for creating a checkpoint library are explained in detail here. Please find below a more elaborate sequence of instructions to build a checkpoint library.
cd QPoints/scripts/qflex
./download_image.sh
mv root.qcow2 /your/desired/folder
Note that the downloaded image has already several snapshots inside.
# make sure you have already run setup.sh
qemu-img snapshot -l root.qcow2
# you will find many snapshots already included in the image
CLEAN from the BASE image with its content set to that of SNAPSHOT. Please set the parameters used in the cleanup script before running it.cd scipts/qflex
# set parameters used in cleanup.sh, i.e., BASE, SNAPSHOT, CLEAN
./cleanup.sh
qemu-img snapshot -l ${CLEAN}
# no output
--core-count 1
--no-double-cores
--quantum-size-ns 2000
--llc-size-per-tile-mb 1
--parallel
--network user
--memory-gb 16
--host-name SAPHIRE_SMT
--workload-name test
--population-seconds 1
--no-consolidated
--primary-ipc 2.0
--primary-core-start 0
--phantom-cpu-ipc 4
--experiment-name test
--image-name clean.qcow2
--image-folder /where/clean.qcow2/is
--mounting-folder /where/emulation/files/written
--check-period-quantum-coeff 53.0
--no-unique --use-image-directly
// skew_access.c
// Allocate ~100 MiB of ints, then endlessly access random indices.
// 90% of accesses go to a 1 MiB "hot" region, with extra skew inside that region.
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
#include <unistd.h>
#include <math.h>
#ifndef TOTAL_BYTES
#define TOTAL_BYTES (100ULL * 1024ULL * 1024ULL) // 100 MiB
#endif
#ifndef HOT_BYTES
#define HOT_BYTES (1ULL * 1024ULL * 1024ULL) // 1 MiB hot region
#endif
#ifndef HOT_PROB_PERCENT
#define HOT_PROB_PERCENT 90 // 90% hot, 10% cold
#endif
#ifndef HOT_ALPHA
#define HOT_ALPHA 2.5 // >1 => more skew toward loww
indices inside hot region
#endif
#ifndef PRINT_EVERY
#define PRINT_EVERY 1000000 // print every access ((
WARNING: very slow / huge output)
#endif
// SplitMix64 RNG (fast, decent quality)
static inline uint64_t splitmix64(uint64_t *state) {
uint64_t z = (*state += 0x9e3779b97f4a7c15ULL);
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9ULL;
z = (z ^ (z >> 27)) * 0x94d049bb133111ebULL;
return z ^ (z >> 31);
}
// Uniform double in [0,1)
static inline double rng_double01(uint64_t *state) {
// Use top 53 bits to build a double
return (splitmix64(state) >> 11) * (1.0 / 9007199254740992.0); // 2^53
}
int main(void) {
const size_t total_count = (size_t)(TOTAL_BYTES / sizeof(int));
const size_t hot_count = (size_t)(HOT_BYTES / sizeof(int));
if (hot_count == 0 || total_count == 0 || hot_count >= total_count) {
fprintf(stderr, "Invalid sizes: hot_count=%zu total_count=%zu\\n", hot_coo
unt, total_count);
return 1;
}
// Allocate the array
int *a = (int*)malloc(total_count * sizeof(int));
if (!a) {
perror("malloc");
return 1;
}
// Initialize (optional, but touches pages so allocation is real)
for (size_t i = 0; i < total_count; i++) a[i] = (int)i;
// Seed RNG
uint64_t rng = (uint64_t)time(NULL) ^ ((uint64_t)getpid() << 32);
volatile int sink = 0; // prevents the compiler from optimizing away reads
uint64_t iter = 0;
while (1) {
// Decide hot vs cold
uint64_t r = splitmix64(&rng);
int pick_hot = (int)(r % 100) < HOT_PROB_PERCENT;
size_t idx;
if (pick_hot) {
// Skewed pick within [0, hot_count)
// u^HOT_ALPHA biases toward 0 when HOT_ALPHA > 1
double u = rng_double01(&rng);
double biased = pow(u, HOT_ALPHA);
idx = (size_t)(biased * (double)hot_count);
if (idx >= hot_count) idx = hot_count - 1;
} else {
// Uniform pick within [hot_count, total_count)
// (cold region excludes the hot region)
size_t cold_span = total_count - hot_count;
idx = hot_count + (size_t)(splitmix64(&rng) % cold_span);
}
sink ^= a[idx]; // actual access
if ((iter % PRINT_EVERY) == 0) {
printf("%zu\\n", idx);
// Optional: fflush(stdout); // uncomment if you want immediate outpu
}
iter++;
}
// Unreachable
// free(a);
// return 0;
}
To compile the code, you first need to install gcc:
su
# just press Enter for password
apk update
apk add gcc
exit
Compile the code:
gcc -O2 -std=c++11 ubench.c -lm -o ubench
run the microbenchmark:
./ubench