Rosetta 2 works by doing an ahead-of-time (AOT) translation of the Intel code to corresponding ARM code. It is able to do this efficiently and easily mainly because the M1 CPU contains a special instruction that switches the memory-ordering model observed by the CPU for that thread into a model equivalent to the Intel x86 model (TSO - total store order). This has to do with how programs can expect memory consistency to work when having multiple processors (i.e. cores in this case).
User's can observe the translation the first time they launch an Intel app on the M1 as the first launch is slow. The translated code is cached and used on subsequent, much faster launches.
If you have a binary that is valid for several different architectures, you can specifically invoke Rosetta 2 by specifying that you want to launch the Intel code. You can do that from the terminal like this:
arch -x86_64 ./mycommand
Note that this setting also applies to any program that the "mycommand" process should choose to run.
If you want to do that for research purposes or just out of "pure interest", then you could just take the instructions you want to translate and add them to a simple application shell (essentially adding them to a simple main()-only C program for example) and run it. The cached, translated version of the program then includes the translated instructions for inspection.
The cache is available in:
There's no immediate way of "bridging" Rosetta 2 to QEMU to allow fast virtualization of Intel Docker images. QEMU contains its own Intel x86 emulation, so you could get it to run Intel Docker images on the M1 without involving Rosetta 2 at all. In this case, "fast" is a very subjective measure.