High-Performance Computer Architecture 11 | Experiment for Control Dependencies

Series: High-Performance Computer Architecture

High-Performance Computer Architecture 11 | Experiment for Control Dependencies

NOTE: The present article does NOT include anything related to the final submission (no answers, no specific values, no results) for the course CS6290 HPCA because of the honor code. Most of the contents in this article is repeating the basic instructions and the directions of the Project 0. More Linux commands are provided as complements to the project’s guidelines.
Please feel free to contact me if this article violates the rules of Georgia Tech and I will immediately delete this article with no doubt.
  1. A Possible Bug

Let’s log in to our virtual machine now. Note you may have the following error while logging in,

[ 3.330168] intel8x0:measure - unreliable DMA position..

This error is because of the shared folder, and if you meet this problem, you can reboot and redo the settings for the shared folder. You may need to try several times until you can work on your machine.

If you don’t meet this error, you are free to continue.

2. Experiment 1: LU Decomposition for 64, 128, 256 -Dimension Matrix

Before we start, we have to make sure that there will be no other .rpt files to avoid any conflicts or overwrites.

$ cd ~/sesc/apps/Splash2/lu
$ rm -rf *.rpt

Then we run the following code to generate the report for decompositions. Note that we have to check lu.err and lu.out to make sure that the simulated run has completed correctly.

$ ~/sesc/sesc.opt -fn64.rpt -c ~/sesc/confs/cmp4-noc.conf -olu.out     -elu.err lu.mipseb -n64 -p1
$ cat lu.err
$ cat lu.out
$ ~/sesc/sesc.opt -fn128.rpt -c ~/sesc/confs/cmp4-noc.conf -olu.out     -elu.err lu.mipseb -n128 -p1
$ cat lu.err
$ cat lu.out
$ ~/sesc/sesc.opt -fn256.rpt -c ~/sesc/confs/cmp4-noc.conf -olu.out     -elu.err lu.mipseb -n256 -p1
$ cat lu.err
$ cat lu.out

After that, we can check whether we have already generated these reports by,

$ ls *.rpt

The output should be,

sesc_lu.mipseb.n128.rpt  sesc_lu.mipseb.n256.rpt  sesc_lu.mipseb.n64.rpt

Now we can view these reports by,

$ clear
$ ~/sesc/scripts/report.pl sesc_lu.mipseb.n64.rpt
$ ~/sesc/scripts/report.pl sesc_lu.mipseb.n128.rpt
$ ~/sesc/scripts/report.pl sesc_lu.mipseb.n256.rpt

It is quite interesting to see the improvement for these three files.

3. Experiment 2: Compiling and simulating a small application

Let’s now go to the ~/sesc/tests/ directory and find the hello.c file here,

$ cd ~/sesc/tests/
$ ls

Use any editor (gedit is a good choice) to edit this file so that the string in this program would be (remember to replace the name with your own name),

"Hi there! My name is Adam Edelweiss\n"

Use cat to check out the content,

$ cat hello.c

Now we should gcc try to compile and run our code natively,

$ gcc -o hello hello.c
$ ./hello

This should result in printing out the “Hi there! My name is ….” message and then a newline.

Because the simulator uses the MIPS ISA, we cannot use the native compiler. Instead, we use a cross-compiler — it is a compiler that runs on one machine (the native machine) but produces code for a different machine (the target machine, i.e. MIPS). Installing and setting up the cross-compiler is a time-consuming and tricky process, so we have already installed one and made it ready for you to use.

The cross-compiler can be found in /mipsroot/cross-tools/bin with a name 
mips-unknown-linux-gnu-gcc. We can check it by,

$ ls /mipsroot/cross-tools/bin | grep mips-unknown-linux-gnu-gcc

The output should be,

mips-unknown-linux-gnu-gcc
mips-unknown-linux-gnu-gcc-4.6.3

and the one we need is the mips-unknown-linux-gnu-gcc one.

Notice that there are many other cross-compilation tools for us. We can print the name of them by,

$ ls /mipsroot/cross-tools/bin | grep mips-unknown-linux-gnu-*

The output should be,

mips-unknown-linux-gnu-addr2line
mips-unknown-linux-gnu-ar
mips-unknown-linux-gnu-as
mips-unknown-linux-gnu-c++
mips-unknown-linux-gnu-c++filt
mips-unknown-linux-gnu-cpp
mips-unknown-linux-gnu-elfedit
mips-unknown-linux-gnu-g++
mips-unknown-linux-gnu-gcc
mips-unknown-linux-gnu-gcc-4.6.3
mips-unknown-linux-gnu-gcov
mips-unknown-linux-gnu-gfortran
mips-unknown-linux-gnu-gprof
mips-unknown-linux-gnu-ld
mips-unknown-linux-gnu-ld.bfd
mips-unknown-linux-gnu-nm
mips-unknown-linux-gnu-objcopy
mips-unknown-linux-gnu-objdump
mips-unknown-linux-gnu-ranlib
mips-unknown-linux-gnu-readelf
mips-unknown-linux-gnu-size
mips-unknown-linux-gnu-strings
mips-unknown-linux-gnu-strip

Now, let’s simulate our hello.c . Firstly, let’s compile our hello.c by mips-unknown-linux-gnu-gcc,

$ /mipsroot/cross-tools/bin/mips-unknown-linux-gnu-gcc -O0 -g -static -mabi=32 -fno-delayed-branch -fno-optimize-sibling-calls -msplit-addresses -march=mips4 -o hello.mipseb hello.c

After the compiler generates the MIPS executable file hello.mipseb for us. We can check this by,

$ ls *.mipseb

Now, let’s generate the report .rpt file for us and then read into this report by the report.pl file,

$ ~/sesc/sesc.opt -fhello0.rpt -c ~/sesc/confs/cmp4-noc.conf -ohello.out hello.mipseb
$ ~/sesc/scripts/report.pl sesc_hello.mipseb.hello0.rpt

To understand why we have so many instructions for this simple script, we can have a look at the result produced by the disassembler mips-unknown-linux-gnu-objdump.

$ /mipsroot/cross-tools/bin/mips-unknown-linux-gnu-objdump -d hello.mipseb | more

To find where we actually execute the main function, we can search for <main> in this result,

$ /mipsroot/cross-tools/bin/mips-unknown-linux-gnu-objdump -d hello.mipseb | grep "<main>"

Note that we can find many instructions executed before the main function. How come? Let’s run the following code to see the first ten lines. You may see something about the _init . To know more about this, we have to look up the documentation for the __libc_start_main function which is part of the GNU standard C library (GLIBC) from here,

$ /mipsroot/cross-tools/bin/mips-unknown-linux-gnu-objdump -d hello.mipseb | head -10

The tool mips-unknown-linux-gnu-strip will discard symbols from object files to reduce its code size without breaking it.

$ /mipsroot/cross-tools/bin/mips-unknown-linux-gnu-strip hello.mipseb

Now, let’s add an exclamation mark ! to the string that is printed,

"Hi there! My name is Adam Edelweiss!\n"

Then we redo the MIPS ISA compiling by mips-unknown-linux-gnu-gcc,

$ /mipsroot/cross-tools/bin/mips-unknown-linux-gnu-gcc -O0 -g -static -mabi=32 -fno-delayed-branch -fno-optimize-sibling-calls -msplit-addresses -march=mips4 -o hello.mipseb hello.c

Then we use the simulator to generate a new report named sesc_hello.mipseb.hello1.rpt and then read its content,

$ ~/sesc/sesc.opt -fhello1.rpt -c ~/sesc/confs/cmp4-noc.conf -ohello.out hello.mipseb
$ ~/sesc/scripts/report.pl sesc_hello.mipseb.hello1.rpt

Look at the result of this report, we can find the number of executed instructions for this program. What do you find and how can you explain that? If we continue adding more exclamation marks ! , and redo the report for hello2.rpt , hello3.rpt , hello4.rpt

"Hi there! My name is Adam Edelweiss!!\n"
"Hi there! My name is Adam Edelweiss!!!\n"
"Hi there! My name is Adam Edelweiss!!!!\n"

Then,

$ /mipsroot/cross-tools/bin/mips-unknown-linux-gnu-gcc -O0 -g -static -mabi=32 -fno-delayed-branch -fno-optimize-sibling-calls -msplit-addresses -march=mips4 -o hello.mipseb hello.c
$ ~/sesc/sesc.opt -fhello2.rpt -c ~/sesc/confs/cmp4-noc.conf -ohello.out hello.mipseb
$ ~/sesc/scripts/report.pl sesc_hello.mipseb.hello2.rpt
$ /mipsroot/cross-tools/bin/mips-unknown-linux-gnu-gcc -O0 -g -static -mabi=32 -fno-delayed-branch -fno-optimize-sibling-calls -msplit-addresses -march=mips4 -o hello.mipseb hello.c
$ ~/sesc/sesc.opt -fhello3.rpt -c ~/sesc/confs/cmp4-noc.conf -ohello.out hello.mipseb
$ ~/sesc/scripts/report.pl sesc_hello.mipseb.hello3.rpt
$ /mipsroot/cross-tools/bin/mips-unknown-linux-gnu-gcc -O0 -g -static -mabi=32 -fno-delayed-branch -fno-optimize-sibling-calls -msplit-addresses -march=mips4 -o hello.mipseb hello.c
$ ~/sesc/sesc.opt -fhello4.rpt -c ~/sesc/confs/cmp4-noc.conf -ohello.out hello.mipseb
$ ~/sesc/scripts/report.pl sesc_hello.mipseb.hello4.rpt
...

What else can you find and how can you explain this?

Note that we can also use objdump to see what main is doing (it is actually not calling printf),

$ /mipsroot/cross-tools/bin/mips-unknown-linux-gnu-objdump -d hello.mipseb > desc.txt

Here is a hint, in order to show the functions we call in <main> , we can run

$ /mipsroot/cross-tools/bin/mips-unknown-linux-gnu-objdump -d hello.mipseb | grep -A 5000 "<main>" | grep -e "<.*>:"

4. Final Delivery

Check the existence of the following files before submission,

PRJ0.docx
sesc_lu.mipseb.n64.rpt
sesc_lu.mipseb.n128.rpt
sesc_lu.mipseb.n256.rpt
hello.c // with exclamation marks for fewer instructions
sesc_hello.mipseb.hello0.rpt
sesc_hello.mipseb.hello?.rpt // last simulation, ? must be replaced