mops: document hardcoding them into benchmarks

This commit is contained in:
Ciro Santilli
2018-05-29 00:21:04 +01:00
parent 29941dea24
commit ee07553278
2 changed files with 108 additions and 11 deletions

View File

@@ -6127,23 +6127,34 @@ And a second instance:
TODO Now we just need to network them up to have some more fun! See dist-gem5: http://publish.illinois.edu/icsl-pdgem5/
=== m5
=== m5ops
`m5` is a guest command line utility that is installed and run on the guest.
m5ops are magic instructions which lead gem5 to do magic things, like quitting or dumping stats.
Its source is present under the gem5 main tree.
Documentation: http://gem5.org/M5ops
It generates magic instructions, which lead gem5 to do magic things, like `dumpstats` or `exit`.
There are two main ways to use m5ops:
It is however under-documented, so let's document some of its capabilities here.
* <<m5>>
* <<m5ops-instructions>>
Part of those explanations could be deduced from the documentation of the magic instructions themselves: http://gem5.org/M5ops
`m5` is an officially supported tool, and requires zero integration work for you, and no recompilation of your benchmarks of interest.
==== m5 exit
However it is more intrusive that hardcoding the m5ops instructions into the benchmark itself, since it requires a system call on the guest.
==== m5
`m5` is a guest command line utility that is installed and run on the guest, that serves as a CLI front-end for the <<m5ops>>
Its source is present in the gem5 tree: https://github.com/gem5/gem5/blob/6925bf55005c118dc2580ba83e0fa10b31839ef9/util/m5/m5.c
It is possible to guess what most tools do from the corresponding <<m5ops>>, but let's at least document the less obvious ones here.
===== m5 exit
Quit gem5 with exit status 0.
==== m5 fail
===== m5 fail
Quit gem5 with the given exit status.
@@ -6151,7 +6162,7 @@ Quit gem5 with the given exit status.
m5 fail 1
....
==== m5 writefile
===== m5 writefile
Send a guest file to the host. <<9p>> is a more advanced alternative.
@@ -6174,7 +6185,7 @@ Does not work for subdirectories, gem5 crashes:
m5 writefile myfileguest mydirhost/myfilehost
....
==== m5 readfile
===== m5 readfile
https://stackoverflow.com/questions/49516399/how-to-use-m5-readfile-and-m5-execfile-in-gem5/49538051#49538051
@@ -6190,7 +6201,7 @@ Guest:
m5 readfile
....
==== m5 execfile
===== m5 execfile
Host:
@@ -6207,6 +6218,32 @@ chmod +x /tmp/execfile
m5 execfile
....
==== m5ops instructions
The executable m5ops illustrates how to hard code inline assembly the most useful m5ops that you are most likely to hack into the benchmark you are analysing:
....
# checkpoint
/m5ops.out c
# dumpstats
/m5ops.out d
# dump exit
/m5ops.out e
# dump resetstats
/m5ops.out r
....
That executable is of course a subset of <<m5>> and useless by itself: its goal is only illustrate how to hardcode some <<m5ops>> yourself.
In theory, the cleanest way to add m5ops to your benchmarks would be to do exactly what the `m5` tool does:
* include `include/gem5/m5ops.h`
* link with the `.o` file under `util/m5` for the correct arch, e.g. `m5op_arm_A64.o` for aarch64.
However, I think it is usually not worth the trouble of hacking up the build system of the benchmark to do this, and I recommend just hardcoding in a few raw instructions here and there, and managing it with version control + `sed`.
Related: https://www.mail-archive.com/gem5-users@gem5.org/msg15418.html
=== gem5 arm Linux kernel patches
https://gem5.googlesource.com/arm/linux/ contains an ARM Linux kernel fork with a few gem5 specific Linux kernel patches on top of mainline created by ARM Holdings.

View File

@@ -0,0 +1,60 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#define ENABLED 1
#if defined(__aarch64__)
static void m5_checkpoint(uint64_t x, uint64_t y)
{
__asm__ __volatile__ (".inst 0xff430110;":: "r" (x), "r" (y));
};
static void m5_dump_stats(uint64_t x, uint64_t y)
{
__asm__ __volatile__ (".inst 0xff410110;":: "r" (x), "r" (y));
};
static void m5_exit(uint64_t x)
{
__asm__ __volatile__ (".inst 0xff210110;":: "r" (x));
};
static void m5_reset_stats(uint64_t x, uint64_t y)
{
__asm__ __volatile__ (".inst 0xff400110;":: "r" (x), "r" (y));
};
#else
#undef ENABLED
#define ENABLED 0
#endif
int main(
#if ENABLED
int argc, char **argv
#else
void
#endif
)
{
#if defined(__aarch64__)
char action;
if (argc > 1) {
action = argv[1][0];
} else {
action = 'e';
}
switch (action)
{
case 'c':
m5_checkpoint(0, 0);
break;
case 'd':
m5_dump_stats(0, 0);
break;
case 'e':
m5_exit(0);
break;
case 'r':
m5_reset_stats(0, 0);
break;
}
#endif
return EXIT_SUCCESS;
}