akh morn
This commit is contained in:
parent
fc687426ae
commit
b57fe6e5ea
147
util/mornafah.c
147
util/mornafah.c
@ -6,43 +6,84 @@
|
|||||||
#include <topo.h>
|
#include <topo.h>
|
||||||
#include <immintrin.h>
|
#include <immintrin.h>
|
||||||
#include <x86intrin.h>
|
#include <x86intrin.h>
|
||||||
|
#include <stdatomic.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <sys/cpuset.h>
|
#include <sys/cpuset.h>
|
||||||
|
#include <sys/sysctl.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <pthread_np.h>
|
#include <pthread_np.h>
|
||||||
|
|
||||||
#define BUFFER_SIZE (1 * 1024 * 1024)
|
#define BUFFER_SIZE (128 * 1024 * 1024)
|
||||||
|
#define BUFFER_CNT (BUFFER_SIZE / sizeof(int))
|
||||||
|
|
||||||
static _Atomic int flush = 0;
|
static _Atomic int flush = 0;
|
||||||
|
static _Atomic uint64_t offset = 0;
|
||||||
static int * remote_buffer = NULL;
|
static int * remote_buffer = NULL;
|
||||||
static uint64_t latencies[65536] = {0};
|
static uint64_t * latencies;
|
||||||
static int times = 10;
|
static int times = 100;
|
||||||
static int local_core = 0;
|
static int local_core = 0;
|
||||||
static int remote_core = 1;
|
static int remote_core = 1;
|
||||||
static int cache_mode = 0;
|
static int cache_mode = 0;
|
||||||
|
static int verbose = 0;
|
||||||
|
static int random_access = 0;
|
||||||
|
static uint64_t tsc_freq = 0;
|
||||||
|
|
||||||
|
static inline uint64_t cyc2ns(uint64_t cyc)
|
||||||
|
{
|
||||||
|
return (double)cyc / ((double)tsc_freq / 1000000000.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t read_time(void)
|
||||||
|
{
|
||||||
|
uint64_t l;
|
||||||
|
unsigned int a;
|
||||||
|
l = __rdtscp(&a);
|
||||||
|
_mm_lfence();
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
static void * local_thread(void *)
|
static void * local_thread(void *)
|
||||||
{
|
{
|
||||||
int temp;
|
int temp, *addr;
|
||||||
unsigned int dummy;
|
uint64_t start, end;
|
||||||
uint64_t start, end, base;
|
|
||||||
printf("Local thread running...\n");
|
printf("Local thread running...\n");
|
||||||
while(times > 0) {
|
while(times > 0) {
|
||||||
|
if (random_access) {
|
||||||
|
// change offset
|
||||||
|
offset = (rand() % BUFFER_CNT) * sizeof(int);
|
||||||
|
}
|
||||||
|
|
||||||
flush = 1;
|
flush = 1;
|
||||||
while(flush != 0) {
|
while(flush != 0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_mm_clflush(remote_buffer);
|
addr = (int *)((char *)remote_buffer + offset);
|
||||||
|
|
||||||
start = __rdtscp(&dummy);
|
if (verbose > 1) {
|
||||||
end = __rdtscp(&dummy);
|
printf("Local thread(%d): flushing %p.\n", local_core, addr);
|
||||||
base = end - start;
|
}
|
||||||
|
|
||||||
start = __rdtscp(&dummy);
|
_mm_clflushopt(addr);
|
||||||
temp = *remote_buffer;
|
_mm_mfence();
|
||||||
end = __rdtscp(&dummy);
|
|
||||||
|
|
||||||
latencies[times - 1] = end - start - base;
|
atomic_signal_fence(memory_order_seq_cst);
|
||||||
|
|
||||||
|
start = read_time();
|
||||||
|
temp = *addr;
|
||||||
|
end = read_time();
|
||||||
|
|
||||||
|
atomic_signal_fence(memory_order_seq_cst);
|
||||||
|
|
||||||
|
if (verbose > 1) {
|
||||||
|
printf("Local thread(%d): read %p.\n", local_core, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
latencies[times - 1] = end - start;
|
||||||
times--;
|
times--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,14 +93,24 @@ static void * local_thread(void *)
|
|||||||
static void * remote_thread(void *)
|
static void * remote_thread(void *)
|
||||||
{
|
{
|
||||||
int temp;
|
int temp;
|
||||||
|
int * addr;
|
||||||
printf("Remote thread running...\n");
|
printf("Remote thread running...\n");
|
||||||
while(1) {
|
while(1) {
|
||||||
while(flush == 0) {
|
while(flush == 0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addr = (int *)((char *)remote_buffer + offset);
|
||||||
|
|
||||||
if(cache_mode) {
|
if(cache_mode) {
|
||||||
temp = *remote_buffer;
|
temp = *addr;
|
||||||
|
_mm_mfence();
|
||||||
} else {
|
} else {
|
||||||
_mm_clflush(remote_buffer);
|
_mm_clflushopt(addr);
|
||||||
|
_mm_mfence();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose > 1) {
|
||||||
|
printf("Remote thread(%d): %p %s.\n", remote_core, addr, cache_mode ? "read into cache" : "flushed");
|
||||||
}
|
}
|
||||||
|
|
||||||
flush = 0;
|
flush = 0;
|
||||||
@ -72,7 +123,7 @@ int main(int argc, char * argv[])
|
|||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
// parse arguments
|
// parse arguments
|
||||||
while ((c = getopt(argc, argv, "l:r:t:m:")) != -1) {
|
while ((c = getopt(argc, argv, "l:r:t:vR")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'l':
|
case 'l':
|
||||||
local_core = atoi(optarg);
|
local_core = atoi(optarg);
|
||||||
@ -83,8 +134,11 @@ int main(int argc, char * argv[])
|
|||||||
case 't':
|
case 't':
|
||||||
times = atoi(optarg);
|
times = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'R':
|
||||||
cache_mode = atoi(optarg);
|
random_access = 1;
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
verbose++;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -92,6 +146,8 @@ int main(int argc, char * argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
|
||||||
// init topo
|
// init topo
|
||||||
if (topo_init(1)) {
|
if (topo_init(1)) {
|
||||||
fprintf(stderr, "libtopo init failed!\n");
|
fprintf(stderr, "libtopo init failed!\n");
|
||||||
@ -104,12 +160,24 @@ int main(int argc, char * argv[])
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int remote_numa = topo_core_to_numa(remote_core);
|
size_t sz = sizeof(tsc_freq);
|
||||||
int local_numa = topo_core_to_numa(local_core);
|
int rc;
|
||||||
int total = times;
|
if ((rc = sysctlbyname("machdep.tsc_freq", &tsc_freq, &sz, NULL, 0)) < 0) {
|
||||||
|
fprintf(stderr,"failed to query tsc frequency via sysctl (%d)\n", errno);
|
||||||
|
} else {
|
||||||
|
fprintf(stdout,"system tsc frequency = %lu\n", tsc_freq);
|
||||||
|
}
|
||||||
|
|
||||||
remote_buffer = nms_alloc_static(remote_numa, BUFFER_SIZE);
|
latencies = malloc(sizeof(uint64_t) * times);
|
||||||
*remote_buffer = 0xffa5be6c;
|
const int remote_numa = topo_core_to_numa(remote_core);
|
||||||
|
const int local_numa = topo_core_to_numa(local_core);
|
||||||
|
const int total = times;
|
||||||
|
|
||||||
|
remote_buffer = nms_malloc(remote_numa, BUFFER_SIZE);
|
||||||
|
// fill with random values
|
||||||
|
for (int i = 0; i < BUFFER_SIZE; i++) {
|
||||||
|
remote_buffer[i] = rand();
|
||||||
|
}
|
||||||
|
|
||||||
pthread_attr_t lattr, rattr;
|
pthread_attr_t lattr, rattr;
|
||||||
pthread_t lthread, rthread;
|
pthread_t lthread, rthread;
|
||||||
@ -131,12 +199,39 @@ int main(int argc, char * argv[])
|
|||||||
|
|
||||||
pthread_join(lthread, NULL);
|
pthread_join(lthread, NULL);
|
||||||
|
|
||||||
|
uint64_t min = UINT64_MAX;
|
||||||
|
uint64_t max = 0;
|
||||||
uint64_t sum = 0;
|
uint64_t sum = 0;
|
||||||
for (int i = total - 1; i >= 0; i--) {
|
for (int i = total - 1; i >= 0; i--) {
|
||||||
printf("%lu\n", latencies[i]);
|
if (verbose) {
|
||||||
|
printf("%lu,\n", latencies[i]);
|
||||||
|
}
|
||||||
|
if (min > latencies[i]) {
|
||||||
|
min = latencies[i];
|
||||||
|
}
|
||||||
|
if (max < latencies[i]) {
|
||||||
|
max = latencies[i];
|
||||||
|
}
|
||||||
sum += latencies[i];
|
sum += latencies[i];
|
||||||
}
|
}
|
||||||
printf("Avg: %lu\n", sum / total);
|
|
||||||
|
double var = 0.0;
|
||||||
|
double avg = (double)sum / (double)total;
|
||||||
|
for (int i = total - 1; i >= 0; i--) {
|
||||||
|
var += pow(latencies[i] - avg, 2);
|
||||||
|
}
|
||||||
|
var = sqrt(var / avg);
|
||||||
|
|
||||||
|
printf("Avg: %lu cycles (%lu ns)\n"
|
||||||
|
"Std: %lu cycles (%lu ns)\n"
|
||||||
|
"Min: %lu cycles (%lu ns)\n"
|
||||||
|
"Max: %lu cycles (%lu ns)\n",
|
||||||
|
(uint64_t)avg, cyc2ns((uint64_t)avg),
|
||||||
|
(uint64_t)var, cyc2ns((uint64_t)var),
|
||||||
|
min, cyc2ns(min),
|
||||||
|
max, cyc2ns(max));
|
||||||
|
|
||||||
|
free(latencies);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user