提交 fee016c5 编写于 作者: Y Yinan Xu

snapshot: use less memory

上级 a89e9853
......@@ -65,7 +65,7 @@ long readFromGz(void* ptr, const char *file_name, long buf_size, uint8_t load_ty
// Only load from RAM need check
if (load_type == LOAD_RAM && (buf_size % chunk_size) != 0) {
printf("RAMSIZE must be divisible by chunk_size\n");
printf("buf_size must be divisible by chunk_size\n");
assert(0);
}
......@@ -88,7 +88,7 @@ long readFromGz(void* ptr, const char *file_name, long buf_size, uint8_t load_ty
}
if(gzread(compressed_mem, temp_page, chunk_size) > 0) {
printf("File size is larger than RAMSIZE!\n");
printf("File size is larger than buf_size!\n");
assert(0);
}
printf("Read %lu bytes from gz stream in total\n", curr_size);
......@@ -101,3 +101,26 @@ long readFromGz(void* ptr, const char *file_name, long buf_size, uint8_t load_ty
}
return curr_size;
}
void nonzero_large_memcpy(const void* __restrict dest, const void* __restrict src, size_t n) {
uint64_t *_dest = (uint64_t *)dest;
uint64_t *_src = (uint64_t *)src;
while (n >= sizeof(uint64_t)) {
if (*_src != 0) {
*_dest = *_src;
}
_dest++;
_src++;
n -= sizeof(uint64_t);
}
if (n > 0) {
uint8_t *dest8 = (uint8_t *)_dest;
uint8_t *src8 = (uint8_t *)_src;
while (n > 0) {
*dest8 = *src8;
dest8++;
src8++;
n--;
}
}
}
......@@ -15,4 +15,6 @@ int isGzFile(const char *filename);
long snapshot_compressToFile(uint8_t *ptr, const char *filename, long buf_size);
long readFromGz(void* ptr, const char *file_name, long buf_size, uint8_t load_type);
void nonzero_large_memcpy(const void* __restrict dest, const void* __restrict src, size_t n);
#endif
......@@ -4,6 +4,7 @@
#include <getopt.h>
#include "ram.h"
#include "zlib.h"
#include "compress.h"
void* get_ram_start();
long get_ram_size();
......@@ -128,8 +129,10 @@ Emulator::~Emulator() {
ram_finish();
#ifdef VM_SAVABLE
snapshot_slot[0].save();
snapshot_slot[1].save();
if (trapCode != STATE_GOODTRAP && trapCode != STATE_LIMIT_EXCEEDED) {
snapshot_slot[0].save();
snapshot_slot[1].save();
}
printf("Please remove unused snapshots manually\n");
#endif
}
......@@ -317,8 +320,8 @@ uint64_t Emulator::execute(uint64_t max_cycle, uint64_t max_instr) {
}
#ifdef VM_SAVABLE
static int snapshot_count = 0;
if (trapCode != STATE_GOODTRAP && t - lasttime_snapshot > 1000 * SNAPSHOT_INTERVAL) {
// save snapshot every 10s
if (trapCode != STATE_GOODTRAP && t - lasttime_snapshot > 6000 * SNAPSHOT_INTERVAL) {
// save snapshot every 60s
time_t now = time(NULL);
snapshot_save(snapshot_filename(now));
lasttime_snapshot = t;
......@@ -443,7 +446,7 @@ void Emulator::snapshot_save(const char *filename) {
char *buf = new char[size];
ref_difftest_memcpy_from_ref(buf, 0x80000000, size);
stream.unbuf_write(buf, size);
delete buf;
delete [] buf;
struct SyncState sync_mastate;
ref_difftest_get_mastatus(&sync_mastate);
......@@ -484,7 +487,7 @@ void Emulator::snapshot_load(const char *filename) {
char *buf = new char[size];
stream.read(buf, size);
ref_difftest_memcpy_from_dut(0x80000000, buf, size);
delete buf;
delete [] buf;
struct SyncState sync_mastate;
stream.read(&sync_mastate, sizeof(struct SyncState));
......
......@@ -4,7 +4,6 @@
#include "ram.h"
#include "compress.h"
#define RAMSIZE (256 * 1024 * 1024UL)
#ifdef WITH_DRAMSIM3
#include "cosimulation.h"
......@@ -16,7 +15,7 @@ static long img_size = 0;
void* get_img_start() { return &ram[0]; }
long get_img_size() { return img_size; }
void* get_ram_start() { return &ram[0]; }
long get_ram_size() { return RAMSIZE; }
long get_ram_size() { return EMU_RAM_SIZE; }
#ifdef TLB_UNITTEST
void addpageSv39() {
......@@ -109,17 +108,17 @@ void init_ram(const char *img) {
printf("The image is %s\n", img);
// initialize memory using Linux mmap
printf("Using simulated %luMB RAM\n", RAMSIZE / (1024 * 1024));
ram = (uint64_t *)mmap(NULL, RAMSIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
printf("Using simulated %luMB RAM\n", EMU_RAM_SIZE / (1024 * 1024));
ram = (uint64_t *)mmap(NULL, EMU_RAM_SIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
if (ram == (uint64_t *)MAP_FAILED) {
printf("Cound not mmap 0x%lx bytes\n", RAMSIZE);
printf("Cound not mmap 0x%lx bytes\n", EMU_RAM_SIZE);
assert(0);
}
int ret;
if (isGzFile(img)) {
printf("Gzip file detected and loading image from extracted gz file\n");
img_size = readFromGz(ram, img, RAMSIZE, LOAD_RAM);
img_size = readFromGz(ram, img, EMU_RAM_SIZE, LOAD_RAM);
assert(img_size >= 0);
}
else {
......@@ -131,8 +130,8 @@ void init_ram(const char *img) {
fseek(fp, 0, SEEK_END);
img_size = ftell(fp);
if (img_size > RAMSIZE) {
img_size = RAMSIZE;
if (img_size > EMU_RAM_SIZE) {
img_size = EMU_RAM_SIZE;
}
fseek(fp, 0, SEEK_SET);
......@@ -159,24 +158,24 @@ void init_ram(const char *img) {
}
void ram_finish() {
munmap(ram, RAMSIZE);
munmap(ram, EMU_RAM_SIZE);
#ifdef WITH_DRAMSIM3
dramsim3_finish();
#endif
}
extern "C" uint64_t ram_read_helper(uint8_t en, uint64_t rIdx) {
if (en && rIdx >= RAMSIZE / sizeof(uint64_t)) {
rIdx %= RAMSIZE / sizeof(uint64_t);
if (en && rIdx >= EMU_RAM_SIZE / sizeof(uint64_t)) {
rIdx %= EMU_RAM_SIZE / sizeof(uint64_t);
}
return (en) ? ram[rIdx] : 0;
}
extern "C" void ram_write_helper(uint64_t wIdx, uint64_t wdata, uint64_t wmask, uint8_t wen) {
if (wen) {
if (wIdx >= RAMSIZE / sizeof(uint64_t)) {
if (wIdx >= EMU_RAM_SIZE / sizeof(uint64_t)) {
printf("ERROR: ram wIdx = 0x%lx out of bound!\n", wIdx);
assert(wIdx < RAMSIZE / sizeof(uint64_t));
assert(wIdx < EMU_RAM_SIZE / sizeof(uint64_t));
}
ram[wIdx] = (ram[wIdx] & ~wmask) | (wdata & wmask);
}
......@@ -201,7 +200,7 @@ struct dramsim3_meta {
};
void axi_read_data(const axi_ar_channel &ar, dramsim3_meta *meta) {
uint64_t address = ar.addr % RAMSIZE;
uint64_t address = ar.addr % EMU_RAM_SIZE;
uint64_t beatsize = 1 << ar.size;
uint8_t beatlen = ar.len + 1;
uint64_t transaction_size = beatsize * beatlen;
......@@ -350,7 +349,7 @@ void dramsim3_helper(axi_channel &axi) {
axi.b.id = meta->id;
// assert(axi.b.ready == 1);
for (int i = 0; i < meta->len; i++) {
uint64_t address = wait_resp_b->req->address % RAMSIZE;
uint64_t address = wait_resp_b->req->address % EMU_RAM_SIZE;
ram[address / sizeof(uint64_t) + i] = meta->data[i];
}
// printf("axi b channel fired\n");
......
......@@ -3,6 +3,8 @@
#include "common.h"
#define EMU_RAM_SIZE (256 * 1024 * 1024UL)
void init_ram(const char *img);
void ram_finish();
......
......@@ -15,20 +15,23 @@ void VerilatedSaveMem::save() {
if (size == 0) return;
trailer();
flush();
if(size <= (512 * 1024 * 1024UL)){
FILE *fp = fopen(m_filename.c_str(), "w");
auto saved_filename = m_filename;
if (size <= (512 * 1024 * 1024UL)) {
FILE *fp = fopen(saved_filename.c_str(), "w");
assert(fp != NULL);
fwrite(buf, size, 1, fp);
fclose(fp);
} else {
timeval s, e;
gettimeofday(&s, NULL);
snapshot_compressToFile(buf, (m_filename + ".gz").c_str(), size);
gettimeofday(&e, NULL);
printf("Compress cost time (msec.usec): %lf\n", calcTime(s, e));
saved_filename = saved_filename + ".gz";
// timeval s, e;
// gettimeofday(&s, NULL);
snapshot_compressToFile(buf, saved_filename.c_str(), size);
// gettimeofday(&e, NULL);
// printf("Compress cost time (msec.usec): %lf\n", calcTime(s, e));
}
size = 0;
printf("save snapshot to %s...\n", m_filename.c_str());
printf("save snapshot to %s...\n", saved_filename.c_str());
}
void VerilatedRestoreMem::fill() {
......@@ -79,7 +82,7 @@ void VerilatedRestoreMem::open(const char* filename) {
gettimeofday(&s, NULL);
size = readFromGz(buf, filename, buf_size, LOAD_SNAPSHOT);
gettimeofday(&e, NULL);
printf("Uncompress cost time (msec.usec): %lf\n", calcTime(s, e));
// printf("Uncompress cost time (msec.usec): %lf\n", calcTime(s, e));
assert(size > 0);
} else {
FILE *fp = fopen(filename, "r");
......
......@@ -5,33 +5,40 @@
#include "VXSSimSoC.h"
#include <verilated_save.h>
#include <sys/mman.h>
#include "compress.h"
#include "ram.h"
#define SNAPSHOT_SIZE (3 * 16 * 1024 * 1024 * 1024UL)
#define SNAPSHOT_SIZE (3UL * EMU_RAM_SIZE)
class VerilatedSaveMem : public VerilatedSerialize {
const static long buf_size = SNAPSHOT_SIZE;
uint8_t *buf;
uint8_t *buf = NULL;
long size;
public:
VerilatedSaveMem() {
buf = (uint8_t*)mmap(NULL, buf_size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
if (buf == (uint8_t *)MAP_FAILED) {
printf("Cound not mmap 0x%lx bytes\n", SNAPSHOT_SIZE);
assert(0);
}
buf = NULL;
size = 0;
}
~VerilatedSaveMem() { }
void init(const char *filename) {
if (buf != NULL) {
munmap(buf, SNAPSHOT_SIZE);
buf = NULL;
}
buf = (uint8_t*)mmap(NULL, buf_size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
if (buf == (uint8_t *)MAP_FAILED) {
printf("Cound not mmap 0x%lx bytes\n", SNAPSHOT_SIZE);
assert(0);
}
size = 0;
m_filename = filename;
header();
}
void unbuf_write(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
memcpy(buf + this->size, datap, size);
nonzero_large_memcpy(buf + this->size, datap, size);
this->size += size;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册