Skip to content

Commit bfff991

Browse files
Page reuse optimization for Unifico (#28)
The main addition of this patch is a `recode` optimization for the case of unifico. Basically, when we don't want to transform the pages, through the `--no-transform` flag to `crit`, or the `NOTRANSFORM=1` flag to the common makefile, we can reuse the source `pages-1.img` as the destination page. This avoids copying the page, which saves time during `crit recode`. This is a nice and simple trick to actually show the benefit of avoiding the transformation: Unifico only avoids the stack transformation, which happens in `transform_stack_and_regs`, and by itself it cannot show much speedup since the whole `recode` procedure is designed around the assumption that there will be metadata and preprocessing needed to do the transformation. So, lots of bookkeeping from `recode` is hard to avoid even though we don't transform the stack. For this reason, a simple optimization we do it to reuse the page, so we save on copying, which in theory might not be possible for Popcorn (due to differences in the various regions inside the page image, which are not guaranteed not to cause issues if we blindly copy them, while in unifico we imposed as much alignment as possible). * Start simplifying recode in the case of no transformation For now, it just moves the source pages to the destination to avoid copying. This reuse saves some time already. * Restore previous pages-1.img when benchmarking recode This is helpful in our new recode approach where we reuse the src image, but we need to back it up first and restore it, so that we can run this measurement multiple times. * Backup pages image before benchmarking recode Through `hyperfine --setup`, before all the runs, we backup the pages image and then before every run we restore it through `--prepare`. This is because in the `NOTRANSFORM` optimization, we reuse the source page as the destination page, so if we want to measure this multiple times, we need to restore the original source page image. * Add README for benchmarking
1 parent 336392b commit bfff991

3 files changed

Lines changed: 45 additions & 5 deletions

File tree

criu-3.15/lib/py/converter.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,10 @@ def transform_target_mem(self): ##mm, pagemap, pages for vdso, vvar, code_pages
567567
vma['end'] = hex(text_end)
568568
vma['pgoff'] = pg_off
569569

570-
shutil.copyfile(self.src_image_file_paths[PAGES], self.dest_image_file_paths[PAGES])
570+
if self.transform_needed:
571+
shutil.copyfile(self.src_image_file_paths[PAGES], self.dest_image_file_paths[PAGES])
572+
else:
573+
shutil.move(self.src_image_file_paths[PAGES], self.dest_image_file_paths[PAGES])
571574
orig_size = os.stat(self.dest_image_file_paths[PAGES]).st_size
572575
dest_pages = open(self.dest_image_file_paths[PAGES], 'r+b')
573576

@@ -676,8 +679,12 @@ def rewrite_context_init(self, src_handle, src_regset, dest_handle, dest_regset)
676679
dest_sp = src_sp
677680
src_pm = self.src_image_file_paths[PAGEMAP]
678681
dest_pm = self.dest_image_file_paths[PAGEMAP]
679-
src_pages = open(self.src_image_file_paths[PAGES], 'rb')
680-
dest_pages = open(self.dest_image_file_paths[PAGES], 'r+b')
682+
if self.transform_needed:
683+
src_pages = open(self.src_image_file_paths[PAGES], 'rb')
684+
dest_pages = open(self.dest_image_file_paths[PAGES], 'r+b')
685+
else:
686+
src_pages = open(self.dest_image_file_paths[PAGES], 'r+b')
687+
dest_pages = src_pages
681688
(src_st_top_offset, src_st_base_offset) = \
682689
self.get_stack_page_offset(src_pm, src_sp)
683690
(dest_st_top_offset, dest_st_base_offset) = \

experiments/README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Magnifico Experiments
2+
3+
## Steps
4+
5+
The `NOTRANSFORM` flag should be set for the Unifico version, otherwise unset.
6+
7+
```bash
8+
# Depending on the machine you are on
9+
make reduce-noise-{x86,arm}
10+
11+
# Go to the experiment directory
12+
cd <npb>.{unifico,popcorn}.<flag>.<class>
13+
14+
# Single migration and back
15+
make trip-x86-init NOTRANSFORM=
16+
make trip-arm NOTRANSFORM=
17+
make trip-x86-finalize NOTRANSFORM=
18+
19+
# 10 migrations (5 round trips)
20+
make trip-x86-init NOTRANSFORM=
21+
for i in $(seq 5); do
22+
echo $i
23+
make trip-arm NOTRANSFORM=
24+
make trip-x86-continue NOTRANSFORM=
25+
done
26+
# Depending on the number of migration points, a final run might be needed
27+
# This is because the application can allow just enough migrations, so that the
28+
# above loop migrations will be just enough to finish the benchmark.
29+
make trip-x86-finalize NOTRANSFORM=
30+
31+
# Measure recode
32+
make perf-recode-{x86,arm} WARMUP=3 RUNS=3 NOTRANSFORM=
33+
```

experiments/common.mk

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,10 @@ perf-spawn: clean
157157
$(HYPERFINE) '$(RUN_PREPEND) $(CURDIR)/$(BIN)'
158158

159159
perf-recode-x86:
160-
$(HYPERFINE) '$(RUN_PREPEND) $(PYTHON) $(CRIT_RECODE) $(CURDIR) $(CURDIR)/$(ARM_TARGET) $(ARM_TARGET) $(BIN) $(BINDIR) $(DEBUG)'
160+
$(HYPERFINE) --setup 'cp pages-1.img pages-1.backup' --prepare 'cp pages-1.backup pages-1.img' '$(RUN_PREPEND) $(PYTHON) $(CRIT_RECODE) $(CURDIR) $(CURDIR)/$(ARM_TARGET) $(ARM_TARGET) $(BIN) $(BINDIR) $(DEBUG)'
161161

162162
perf-recode-arm:
163-
$(HYPERFINE) '$(RUN_PREPEND) $(PYTHON) $(CRIT_RECODE) $(CURDIR) $(CURDIR)/$(X86_TARGET) $(X86_TARGET) $(BIN) $(BINDIR) $(DEBUG)'
163+
$(HYPERFINE) --setup 'cp pages-1.img pages-1.backup' --prepare 'cp pages-1.backup pages-1.img' '$(RUN_PREPEND) $(PYTHON) $(CRIT_RECODE) $(CURDIR) $(CURDIR)/$(X86_TARGET) $(X86_TARGET) $(BIN) $(BINDIR) $(DEBUG)'
164164

165165
trip-x86-init:
166166
# Go to the x86 QEMU instance and restore, run until a migration point, dump, and recode.

0 commit comments

Comments
 (0)