You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -5530,8 +5530,8 @@ A few imperfections of our benchmarking method are:
5530
5530
5531
5531
Solutions to these problems include:
5532
5532
5533
-
* modify benchmark code with instrumentation directly, as PARSEC and ARM employees have been doing: https://github.com/arm-university/arm-gem5-rsk/blob/aa3b51b175a0f3b6e75c9c856092ae0c8f2a7cdc/parsec_patches/xcompile-patch.diff#L230
5534
-
* monitor known addresses
5533
+
* modify benchmark code with instrumentation directly, see <<m5ops-instructions>> for an example.
5534
+
* monitor known addresses TODO possible? Create an example.
@@ -6243,31 +6243,47 @@ Cycles instead of instructions:
6243
6243
6244
6244
Otherwise the simulation runs forever by default.
6245
6245
6246
-
=== m5
6246
+
=== m5ops
6247
6247
6248
-
`m5` is a guest command line utility that is installed and run on the guest.
6248
+
m5ops are magic instructions which lead gem5 to do magic things, like quitting or dumping stats.
6249
6249
6250
-
Its source is present under the gem5 main tree.
6250
+
Documentation: http://gem5.org/M5ops
6251
6251
6252
-
It generates magic instructions, which lead gem5 to do magic things, like `dumpstats` or `exit`.
6252
+
There are two main ways to use m5ops:
6253
6253
6254
-
It is however under-documented, so let's document some of its capabilities here.
6254
+
* <<m5>>
6255
+
* <<m5ops-instructions>>
6255
6256
6256
-
Part of those explanations could be deduced from the documentation of the magic instructions themselves: http://gem5.org/M5ops
6257
+
`m5` is convenient if you only want to take snapshots before or after the benchmark, without altering its source code. It uses the <<m5ops-instructions>> as its backend.
6257
6258
6258
-
==== m5 exit
6259
+
`m5` cannot should / should not be used however:
6260
+
6261
+
* in bare metal setups
6262
+
* when you want to call the instructions from inside interest points of your benchmark. Otherwise you add the syscall overhead to the benchmark, which is more intrusive and might affect results.
6263
+
+
6264
+
Why not just hardcode some <<m5ops-instructions>> as in our example instead, since you are going to modify the source of the benchmark anyways?
6265
+
6266
+
==== m5
6267
+
6268
+
`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>>
6269
+
6270
+
Its source is present in the gem5 tree: https://github.com/gem5/gem5/blob/6925bf55005c118dc2580ba83e0fa10b31839ef9/util/m5/m5.c
6271
+
6272
+
It is possible to guess what most tools do from the corresponding <<m5ops>>, but let's at least document the less obvious ones here.
6273
+
6274
+
===== m5 exit
6259
6275
6260
6276
Quit gem5 with exit status 0.
6261
6277
6262
-
==== m5 fail
6278
+
===== m5 fail
6263
6279
6264
6280
Quit gem5 with the given exit status.
6265
6281
6266
6282
....
6267
6283
m5 fail 1
6268
6284
....
6269
6285
6270
-
==== m5 writefile
6286
+
===== m5 writefile
6271
6287
6272
6288
Send a guest file to the host. <<9p>> is a more advanced alternative.
6273
6289
@@ -6290,7 +6306,7 @@ Does not work for subdirectories, gem5 crashes:
The executable `/m5ops.out` illustrates how to hard code with inline assembly the m5ops that you are most likely to hack into the benchmark you are analysing:
6345
+
6346
+
....
6347
+
# checkpoint
6348
+
/m5ops.out c
6349
+
# dumpstats
6350
+
/m5ops.out d
6351
+
# dump exit
6352
+
/m5ops.out e
6353
+
# dump resetstats
6354
+
/m5ops.out r
6355
+
....
6356
+
6357
+
Source: link:kernel_module/user/m5ops.c[]
6358
+
6359
+
That executable is of course a subset of <<m5>> and useless by itself: its goal is only illustrate how to hardcode some <<m5ops>> yourself as one-liners.
6360
+
6361
+
In theory, the cleanest way to add m5ops to your benchmarks would be to do exactly what the `m5` tool does:
6362
+
6363
+
* include link:https://github.com/gem5/gem5/blob/05c4c2b566ce351ab217b2bd7035562aa7a76570/include/gem5/asm/generic/m5ops.h[`include/gem5/asm/generic/m5ops.h`]
6364
+
* link with the `.o` file under `util/m5` for the correct arch, e.g. `m5op_arm_A64.o` for aarch64.
6365
+
6366
+
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`.
* link:https://github.com/gem5/gem5/blob/05c4c2b566ce351ab217b2bd7035562aa7a76570/include/gem5/asm/generic/m5ops.h[`include/gem5/asm/generic/m5ops.h`]: defines the magic constants that represent the instructions
6375
+
* link:https://github.com/gem5/gem5/blob/05c4c2b566ce351ab217b2bd7035562aa7a76570/util/m5/m5op_arm_A64.S[`util/m5/m5op_arm_A64.S`]: use the magic constants that represent the instructions using C preprocessor magic
6376
+
* link:https://github.com/gem5/gem5/blob/05c4c2b566ce351ab217b2bd7035562aa7a76570/util/m5/m5.c[`util/m5/m5.c`]: the actual executable. Gets linked to `m5op_arm_A64.S` which defines a function for each m5op.
6377
+
6378
+
We notice that there are two different implementations for each arch:
6379
+
6380
+
* magic instructions, which don't exist in the corresponding arch
6381
+
* magic memory addresses on a given page
6382
+
6383
+
TODO: what is the advantage of magic memory addresses? Because you have to do more setup work by telling the kernel never to touch the magic page. For the magic instructions, the only thing that could go wrong is if you run some crazy kind of fuzzing workload that generates random instructions.
6384
+
6385
+
Then, in aarch64 magic instructions for example, the lines:
define a simple function function for each m5op. Here we see that:
6396
+
6397
+
* `0xff000110` is a base mask for the magic non-existing instruction
6398
+
* `\func` and `\subfunc` are OR-applied on top of the base mask, and define m5op this is.
6399
+
+
6400
+
Those values will loop over the magic constants defined in `m5ops.h` with the deferred preprocessor idiom.
6401
+
+
6402
+
For example, `exit` is `0x21` due to:
6403
+
+
6404
+
....
6405
+
#define M5OP_EXIT 0x21
6406
+
....
6407
+
6408
+
Finally, `m5.c` calls the defined functions as in:
6409
+
6410
+
....
6411
+
m5_exit(ints[0]);
6412
+
....
6413
+
6414
+
Therefore, the runtime "argument" that gets passed to the instruction, e.g. the desired exit status in the case of `exit`, gets passed directly through the link:https://en.wikipedia.org/wiki/Calling_convention#ARM_(A64)[aarch64 calling convention].
6415
+
6416
+
That convention specifies that `x0` to `x7` contain the function arguments, so `x0` contains the first argument, and `x1` the second.
6417
+
6418
+
In our `m5ops` example, we just hardcode everything in the assembly one-liners we are producing.
6419
+
6420
+
We ignore the `\subfunc` since it is always 0 on the ops that interest us.
6421
+
6422
+
===== m5op annotations
6423
+
6424
+
`include/gem5/asm/generic/m5ops.h` also describes some annotation instructions.
6425
+
6426
+
What they mean: https://stackoverflow.com/questions/50583962/what-are-the-gem5-annotations-mops-magic-instructions-and-how-to-use-them
6427
+
6326
6428
=== gem5 arm Linux kernel patches
6327
6429
6328
6430
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.
0 commit comments