This is a Rust implementation of the UM-32 "Universal Machine". You can find the specification, various VM images, and more information about the contest which originally spawned this horror at boundvariable.org.
The Universal Machine consists of 8 unsigned 32 bit registers, a dynamically allocated heap containing arbitrarily sized arrays of unsigned 32 bit data, and 14 opcodes. Universal Machine images are stored as a sequence of unsigned 32 bit words with big-endian byte order.
This is an extremely naive implementation written as an exercise to become better acquainted with Rust. It's currently a bit slower than Joe's C++ implementation. I'd like to correct this.
There is good coverage of the instruction parsing code, and no coverage of anything else. This will need to be fixed before trying to optimize.
```
[jgrillo@localhost um32]$ sudo lshw -class cpu
*-cpu
description: CPU
product: Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz
vendor: Intel Corp.
physical id: 6
bus info: cpu@0
version: Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz
serial: None
slot: U3E1
size: 1392MHz
capacity: 4005MHz
width: 64 bits
clock: 100MHz
capabilities: x86-64 fpu fpuexception wp vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp constanttsc art archperfmon pebs bts repgood nopl xtopology nonstoptsc cpuid aperfmperf tscknownfreq pni pclmulqdq dtes64 monitor dscpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse41 sse42 x2apic movbe popcnt tscdeadlinetimer aes xsave avx f16c rdrand lahflm abm 3dnowprefetch cpuidfault epb invpcidsingle pti retpoline intelpt tprshadow vnmi flexpriority ept vpid fsgsbase tscadjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwpnotify hwpactwindow hwpepp cpufreq
configuration: cores=4 enabledcores=4 threads=8
[jgrillo@localhost um32]$ time ./target/release/um32 ~/src/boundvariable/umbin/midmark.um
read 120440 bytes from /home/jgrillo/src/boundvariable/umbin/midmark.um
== UM beginning stress test / benchmark.. ==
4. 12345678.09abcdef
3. 6d58165c.2948d58d
2. 0f63b9ed.1d9c4076
1. 8dba0fc0.64af8685
0. 583e02ae.490775c0
Benchmark complete.
real 0m0.640s user 0m0.634s sys 0m0.006s
[jgrillo@localhost um32]$ time ./target/release/um32 ~/src/boundvariable/sandmark.umz read 56364 bytes from /home/jgrillo/src/boundvariable/sandmark.umz trying to Allocate array of size 0.. trying to Abandon size 0 allocation.. trying to Allocate size 11.. trying Array Index on allocated array.. trying Amendment of allocated array.. checking Amendment of allocated array.. trying Alloc(a,a) and amending it.. comparing multiple allocations.. pointer arithmetic.. check old allocation.. simple tests ok! about to load program from some allocated array.. success. verifying that the array and its copy are the same... success. testing aliasing.. success. free after loadprog.. success. loadprog ok. == SANDmark 19106 beginning stress test / benchmark.. == 100. 12345678.09abcdef 99. 6d58165c.2948d58d 98. 0f63b9ed.1d9c4076
...
real 0m39.053s user 0m38.979s sys 0m0.004s
``
According to [this source](https://github.com/rlew/um/tree/master/ums), the
midmark.um` benchmark should run in "about one second".
These blog posts provide a helpful introduction to profiling Rust programs: 1. http://blog.adamperry.me/rust/2016/07/24/profiling-rust-perf-flamegraph/ 2. http://www.codeofview.com/fix-rs/2017/01/24/how-to-optimize-rust-programs-on-linux/