Implement the clock offset correction
This commit is contained in:
parent
4e971bceff
commit
e6e976023d
10
dump.c
10
dump.c
@ -12,16 +12,6 @@
|
|||||||
#include "ovni_trace.h"
|
#include "ovni_trace.h"
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
|
|
||||||
#define ENABLE_DEBUG
|
|
||||||
|
|
||||||
#ifdef ENABLE_DEBUG
|
|
||||||
#define dbg(...) fprintf(stderr, __VA_ARGS__);
|
|
||||||
#else
|
|
||||||
#define dbg(...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define err(...) fprintf(stderr, __VA_ARGS__);
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hexdump(uint8_t *buf, size_t size)
|
hexdump(uint8_t *buf, size_t size)
|
||||||
|
208
emu.c
208
emu.c
@ -8,12 +8,20 @@
|
|||||||
#include <stdatomic.h>
|
#include <stdatomic.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "ovni.h"
|
#include "ovni.h"
|
||||||
#include "ovni_trace.h"
|
#include "ovni_trace.h"
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "prv.h"
|
#include "prv.h"
|
||||||
|
|
||||||
|
/* Obtains the corrected clock of the given event */
|
||||||
|
int64_t
|
||||||
|
evclock(struct ovni_stream *stream, struct ovni_ev *ev)
|
||||||
|
{
|
||||||
|
return (int64_t) ovni_ev_get_clock(ev) + stream->clock_offset;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
emit_ev(struct ovni_stream *stream, struct ovni_ev *ev)
|
emit_ev(struct ovni_stream *stream, struct ovni_ev *ev)
|
||||||
{
|
{
|
||||||
@ -24,7 +32,7 @@ emit_ev(struct ovni_stream *stream, struct ovni_ev *ev)
|
|||||||
//dbg("sizeof(*ev) = %d\n", sizeof(*ev));
|
//dbg("sizeof(*ev) = %d\n", sizeof(*ev));
|
||||||
//hexdump((uint8_t *) ev, sizeof(*ev));
|
//hexdump((uint8_t *) ev, sizeof(*ev));
|
||||||
|
|
||||||
clock = ovni_ev_get_clock(ev);
|
clock = evclock(stream, ev);
|
||||||
|
|
||||||
delta = clock - stream->lastclock;
|
delta = clock - stream->lastclock;
|
||||||
|
|
||||||
@ -126,7 +134,8 @@ next_event(struct ovni_emu *emu)
|
|||||||
struct ovni_ev *ev;
|
struct ovni_ev *ev;
|
||||||
struct ovni_stream *stream;
|
struct ovni_stream *stream;
|
||||||
struct ovni_trace *trace;
|
struct ovni_trace *trace;
|
||||||
static int64_t t0 = -1;
|
|
||||||
|
static int done_first = 0;
|
||||||
|
|
||||||
trace = &emu->trace;
|
trace = &emu->trace;
|
||||||
|
|
||||||
@ -144,10 +153,10 @@ next_event(struct ovni_emu *emu)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
ev = stream->cur_ev;
|
ev = stream->cur_ev;
|
||||||
if(f < 0 || ovni_ev_get_clock(ev) < minclock)
|
if(f < 0 || evclock(stream, ev) < minclock)
|
||||||
{
|
{
|
||||||
f = i;
|
f = i;
|
||||||
minclock = ovni_ev_get_clock(ev);
|
minclock = evclock(stream, ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,18 +168,21 @@ next_event(struct ovni_emu *emu)
|
|||||||
|
|
||||||
set_current(emu, stream);
|
set_current(emu, stream);
|
||||||
|
|
||||||
if(emu->lastclock > ovni_ev_get_clock(stream->cur_ev))
|
if(emu->lastclock > evclock(stream, stream->cur_ev))
|
||||||
{
|
{
|
||||||
fprintf(stdout, "warning: backwards jump in time %lu -> %lu\n",
|
fprintf(stdout, "warning: backwards jump in time %lu -> %lu\n",
|
||||||
emu->lastclock, ovni_ev_get_clock(stream->cur_ev));
|
emu->lastclock, evclock(stream, stream->cur_ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
emu->lastclock = ovni_ev_get_clock(stream->cur_ev);
|
emu->lastclock = evclock(stream, stream->cur_ev);
|
||||||
|
|
||||||
if(t0 < 0)
|
if(!done_first)
|
||||||
t0 = emu->lastclock;
|
{
|
||||||
|
done_first = 1;
|
||||||
|
emu->firstclock = emu->lastclock;
|
||||||
|
}
|
||||||
|
|
||||||
emu->delta_time = emu->lastclock - t0;
|
emu->delta_time = emu->lastclock - emu->firstclock;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -376,44 +388,162 @@ close_prvs(struct ovni_emu *emu)
|
|||||||
fclose(emu->prv_cpu);
|
fclose(emu->prv_cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
usage(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
err("Usage: emu [-c offsetfile] tracedir\n");
|
||||||
|
err("\n");
|
||||||
|
err("Options:\n");
|
||||||
|
err(" -c offsetfile Use the given offset file to correct\n");
|
||||||
|
err(" the clocks among nodes. It can be\n");
|
||||||
|
err(" generated by the ovnisync program\n");
|
||||||
|
err("\n");
|
||||||
|
err(" tracedir The output trace dir generated by ovni.\n");
|
||||||
|
err("\n");
|
||||||
|
err("The output PRV files are placed in the tracedir directory.\n");
|
||||||
|
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_args(struct ovni_emu *emu, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int opt;
|
||||||
|
|
||||||
|
while((opt = getopt(argc, argv, "c:")) != -1)
|
||||||
|
{
|
||||||
|
switch(opt)
|
||||||
|
{
|
||||||
|
case 'c':
|
||||||
|
emu->clock_offset_file = optarg;
|
||||||
|
break;
|
||||||
|
default: /* '?' */
|
||||||
|
usage(argc, argv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(optind >= argc)
|
||||||
|
{
|
||||||
|
err("missing tracedir\n");
|
||||||
|
usage(argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
emu->tracedir = argv[optind];
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct ovni_loom *
|
||||||
|
find_loom_by_hostname(struct ovni_emu *emu, char *host)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct ovni_loom *loom;
|
||||||
|
|
||||||
|
for(i=0; i<emu->trace.nlooms; i++)
|
||||||
|
{
|
||||||
|
loom = &emu->trace.loom[i];
|
||||||
|
|
||||||
|
if(strcmp(loom->hostname, host) == 0)
|
||||||
|
return loom;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
load_clock_offsets(struct ovni_emu *emu)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
char buf[1024];
|
||||||
|
int i, rank;
|
||||||
|
double offset, std;
|
||||||
|
char host[HOST_NAME_MAX];
|
||||||
|
struct ovni_loom *loom;
|
||||||
|
struct ovni_trace *trace;
|
||||||
|
struct ovni_stream *stream;
|
||||||
|
|
||||||
|
f = fopen(emu->clock_offset_file, "r");
|
||||||
|
|
||||||
|
if(f == NULL)
|
||||||
|
{
|
||||||
|
perror("fopen clock offset file failed\n");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ignore header line */
|
||||||
|
fgets(buf, 1024, f);
|
||||||
|
|
||||||
|
while(fscanf(f, "%d %s %lf %lf", &rank, host, &offset, &std) == 4)
|
||||||
|
{
|
||||||
|
loom = find_loom_by_hostname(emu, host);
|
||||||
|
|
||||||
|
if(loom == NULL)
|
||||||
|
{
|
||||||
|
err("No loom has hostname %s\n", host);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(loom->clock_offset != 0)
|
||||||
|
{
|
||||||
|
err("warning: loom at host %s already has a clock offset\n",
|
||||||
|
host);
|
||||||
|
}
|
||||||
|
|
||||||
|
loom->clock_offset = (int64_t) offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Then populate the stream offsets */
|
||||||
|
|
||||||
|
trace = &emu->trace;
|
||||||
|
|
||||||
|
for(i=0; i<trace->nstreams; i++)
|
||||||
|
{
|
||||||
|
stream = &trace->stream[i];
|
||||||
|
loom = &trace->loom[stream->loom];
|
||||||
|
stream->clock_offset = loom->clock_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
emu_init(struct ovni_emu *emu, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
memset(emu, 0, sizeof(emu));
|
||||||
|
|
||||||
|
parse_args(emu, argc, argv);
|
||||||
|
|
||||||
|
if(ovni_load_trace(&emu->trace, emu->tracedir))
|
||||||
|
abort();
|
||||||
|
|
||||||
|
if(ovni_load_streams(&emu->trace))
|
||||||
|
abort();
|
||||||
|
|
||||||
|
if(load_metadata(emu) != 0)
|
||||||
|
abort();
|
||||||
|
|
||||||
|
if(emu->clock_offset_file != NULL)
|
||||||
|
load_clock_offsets(emu);
|
||||||
|
|
||||||
|
open_prvs(emu, emu->tracedir);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
emu_destroy(struct ovni_emu *emu)
|
||||||
|
{
|
||||||
|
close_prvs(emu);
|
||||||
|
destroy_metadata(emu);
|
||||||
|
ovni_free_streams(&emu->trace);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
char *tracedir;
|
|
||||||
struct ovni_emu emu;
|
struct ovni_emu emu;
|
||||||
|
|
||||||
if(argc != 2)
|
emu_init(&emu, argc, argv);
|
||||||
{
|
|
||||||
fprintf(stderr, "missing tracedir\n");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
tracedir = argv[1];
|
|
||||||
|
|
||||||
memset(&emu, 0, sizeof(emu));
|
|
||||||
|
|
||||||
if(ovni_load_trace(&emu.trace, tracedir))
|
|
||||||
abort();
|
|
||||||
|
|
||||||
if(ovni_load_streams(&emu.trace))
|
|
||||||
abort();
|
|
||||||
|
|
||||||
if(load_metadata(&emu) != 0)
|
|
||||||
abort();
|
|
||||||
|
|
||||||
open_prvs(&emu, tracedir);
|
|
||||||
|
|
||||||
printf("#Paraver (19/01/38 at 03:14):00000000000000000000_ns:0:1:1(%d:1)\n", emu.total_cpus);
|
|
||||||
|
|
||||||
emulate(&emu);
|
emulate(&emu);
|
||||||
|
|
||||||
close_prvs(&emu);
|
emu_destroy(&emu);
|
||||||
|
|
||||||
destroy_metadata(&emu);
|
|
||||||
|
|
||||||
ovni_free_streams(&emu.trace);
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
13
emu.h
13
emu.h
@ -8,8 +8,6 @@
|
|||||||
|
|
||||||
/* Debug macros */
|
/* Debug macros */
|
||||||
|
|
||||||
#define ENABLE_DEBUG
|
|
||||||
|
|
||||||
#ifdef ENABLE_DEBUG
|
#ifdef ENABLE_DEBUG
|
||||||
# define dbg(...) fprintf(stderr, __VA_ARGS__);
|
# define dbg(...) fprintf(stderr, __VA_ARGS__);
|
||||||
#else
|
#else
|
||||||
@ -140,13 +138,15 @@ struct ovni_cpu {
|
|||||||
/* State of each loom on post-process */
|
/* State of each loom on post-process */
|
||||||
struct ovni_loom {
|
struct ovni_loom {
|
||||||
size_t nprocs;
|
size_t nprocs;
|
||||||
char name[HOST_NAME_MAX];
|
char hostname[HOST_NAME_MAX];
|
||||||
|
|
||||||
int max_ncpus;
|
int max_ncpus;
|
||||||
int max_phyid;
|
int max_phyid;
|
||||||
int ncpus;
|
int ncpus;
|
||||||
struct ovni_cpu cpu[OVNI_MAX_CPU];
|
struct ovni_cpu cpu[OVNI_MAX_CPU];
|
||||||
|
|
||||||
|
int64_t clock_offset;
|
||||||
|
|
||||||
/* Virtual CPU */
|
/* Virtual CPU */
|
||||||
struct ovni_cpu vcpu;
|
struct ovni_cpu vcpu;
|
||||||
|
|
||||||
@ -173,6 +173,7 @@ struct ovni_stream {
|
|||||||
int active;
|
int active;
|
||||||
struct ovni_ev *cur_ev;
|
struct ovni_ev *cur_ev;
|
||||||
uint64_t lastclock;
|
uint64_t lastclock;
|
||||||
|
int64_t clock_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ovni_emu {
|
struct ovni_emu {
|
||||||
@ -187,12 +188,16 @@ struct ovni_emu {
|
|||||||
|
|
||||||
struct nosv_task *cur_task;
|
struct nosv_task *cur_task;
|
||||||
|
|
||||||
uint64_t lastclock;
|
int64_t firstclock;
|
||||||
|
int64_t lastclock;
|
||||||
int64_t delta_time;
|
int64_t delta_time;
|
||||||
|
|
||||||
FILE *prv_thread;
|
FILE *prv_thread;
|
||||||
FILE *prv_cpu;
|
FILE *prv_cpu;
|
||||||
|
|
||||||
|
char *clock_offset_file;
|
||||||
|
char *tracedir;
|
||||||
|
|
||||||
/* Total counters */
|
/* Total counters */
|
||||||
int total_thread;
|
int total_thread;
|
||||||
int total_proc;
|
int total_proc;
|
||||||
|
@ -252,7 +252,9 @@ hook_pre_ovni(struct ovni_emu *emu)
|
|||||||
{
|
{
|
||||||
case 'H': ev_thread(emu); break;
|
case 'H': ev_thread(emu); break;
|
||||||
case 'A': ev_affinity(emu); break;
|
case 'A': ev_affinity(emu); break;
|
||||||
case 'B': dbg("burst %c\n", emu->cur_ev->header.value); break;
|
case 'B':
|
||||||
|
//dbg("burst %c\n", emu->cur_ev->header.value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
dbg("unknown ovni event class %c\n",
|
dbg("unknown ovni event class %c\n",
|
||||||
emu->cur_ev->header.class);
|
emu->cur_ev->header.class);
|
||||||
|
23
ovni.c
23
ovni.c
@ -21,16 +21,6 @@
|
|||||||
#include "ovni_trace.h"
|
#include "ovni_trace.h"
|
||||||
#include "parson.h"
|
#include "parson.h"
|
||||||
|
|
||||||
#define ENABLE_DEBUG
|
|
||||||
|
|
||||||
#ifdef ENABLE_DEBUG
|
|
||||||
#define dbg(...) fprintf(stderr, __VA_ARGS__);
|
|
||||||
#else
|
|
||||||
#define dbg(...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define err(...) fprintf(stderr, __VA_ARGS__);
|
|
||||||
|
|
||||||
//#define ENABLE_SLOW_CHECKS
|
//#define ENABLE_SLOW_CHECKS
|
||||||
|
|
||||||
//#define USE_RDTSC
|
//#define USE_RDTSC
|
||||||
@ -661,11 +651,7 @@ load_proc(struct ovni_eproc *proc, int index, int pid, char *procdir)
|
|||||||
while((dirent = readdir(dir)) != NULL)
|
while((dirent = readdir(dir)) != NULL)
|
||||||
{
|
{
|
||||||
if(find_dir_prefix_int(dirent, "thread", &tid) != 0)
|
if(find_dir_prefix_int(dirent, "thread", &tid) != 0)
|
||||||
{
|
|
||||||
err("warning: ignoring bogus directory entry %s\n",
|
|
||||||
dirent->d_name);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
sprintf(path, "%s/%s", procdir, dirent->d_name);
|
sprintf(path, "%s/%s", procdir, dirent->d_name);
|
||||||
|
|
||||||
@ -710,11 +696,7 @@ load_loom(struct ovni_loom *loom, int loomid, char *loomdir)
|
|||||||
while((dirent = readdir(dir)) != NULL)
|
while((dirent = readdir(dir)) != NULL)
|
||||||
{
|
{
|
||||||
if(find_dir_prefix_int(dirent, "proc", &pid) != 0)
|
if(find_dir_prefix_int(dirent, "proc", &pid) != 0)
|
||||||
{
|
|
||||||
err("warning: ignoring bogus directory entry %s\n",
|
|
||||||
dirent->d_name);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
sprintf(path, "%s/%s", loomdir, dirent->d_name);
|
sprintf(path, "%s/%s", loomdir, dirent->d_name);
|
||||||
|
|
||||||
@ -777,7 +759,7 @@ ovni_load_trace(struct ovni_trace *trace, char *tracedir)
|
|||||||
loom = &trace->loom[i];
|
loom = &trace->loom[i];
|
||||||
|
|
||||||
/* FIXME: Unsafe */
|
/* FIXME: Unsafe */
|
||||||
strcpy(loom->name, loom_name);
|
strcpy(loom->hostname, loom_name);
|
||||||
|
|
||||||
sprintf(path, "%s/%s", tracedir, dirent->d_name);
|
sprintf(path, "%s/%s", tracedir, dirent->d_name);
|
||||||
|
|
||||||
@ -861,7 +843,7 @@ ovni_load_streams(struct ovni_trace *trace)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "loaded %d streams\n", trace->nstreams);
|
err("loaded %d streams\n", trace->nstreams);
|
||||||
|
|
||||||
for(s=0, i=0; i<trace->nlooms; i++)
|
for(s=0, i=0; i<trace->nlooms; i++)
|
||||||
{
|
{
|
||||||
@ -918,7 +900,6 @@ ovni_load_next_event(struct ovni_stream *stream)
|
|||||||
{
|
{
|
||||||
stream->cur_ev = (struct ovni_ev *) stream->buf;
|
stream->cur_ev = (struct ovni_ev *) stream->buf;
|
||||||
stream->offset = 0;
|
stream->offset = 0;
|
||||||
dbg("first event\n");
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user