Written Assignment 6

Question 1

There are two optimization blockers: procedure calls and memory aliasing.

Procedure Calls

Procedure calls refer to calling to a non-in-lined procedure(function). Because a procedure can change the global state of the program, the procedure is often treated as a black box to the compiler. Therefore, compiler cannot optimize it to have less call to procedure because the procedure may generate side-effects.

There are two possible remedies:

  1. add inline flag to the procedure so that the compiler will consider optimize it. (like opening the black box)
  2. optimize it yourself by calling the procedure once and store its value.

Memory Aliasing

When two variable belong to the same space in memory, optimizations can be hindered because behavior of memory manipulation can change based on whether two inputs shares the same region of memory. Because the compiler needs to consider every edge case (where two pointers can point to the same region of memory), it cannot optimize memory access out.

There are two possible remedies:

  1. add restrict to two arguments indicate that these addresses does not share the same region of memory. (will cause undefined behavior if they actually do)
  2. optimize it yourself by using a variable (such as accumulator) outside of loop.

Question 2

There are 3 rules

  1. Multiple strong symbols are not allowed.
  2. Given a strong symbol and multiple weak symbols, the symbol is defined by strong symbol.
  3. If there are multiple weak symbols, pick an arbitrary one

a

Since both modules have strong definition of symbol main, based on rule 1, compilation will result in error.

b

Based on Piazza Post, void x is not allowed. The TAs have promised to update it but nothing get resolved as for July.12. So I will assume void x; be fixed as int x; in the following answer.

Module 1 has strong symbol x and weak symbol main, and module 2 has weak symbols x and strong symbol main. So according to rule 2, t x will be defined by module 1 and main will be defined by module 2.

c

Module 1 has 2 strong symbols y and main, and module 2 has 3 weak symbols x, y, and main. Therefore, according to rule 2, y and main will be defined by module 1. Notice there are two type mismatch which may reduce code readability and they are hard to debug with.

d

Module 1 has strong symbol z and 2 weak symbols x and y, and module 2 has 3 weak symbols x, y, and z. Therefore, according to rule 2, z will be defined by module 1. There are multiple weak definition of x, and y with different type. According to rule 3, compiler will pick an arbitrary one.

e

Module 1 has strong symbol y and 3 weak symbols main, x, and p. Module 2 has strong symbols x and 2 weak symbols main and y. Therefore, according to rule 2, y will be defined by module 1 and x will be defined by module 2. Notice there are type mismatch for main, x, and y, which may reduce code readability and they are hard to debug with. Also, there are multiple weak definition of main, and therefore, according to rule 3, compiler will pick an arbitrary one.

Question 3

Hypothesis: Since all incorrect values are related to dirty bytes and everything else work correctly, it is very likely that procedures for write to memory is not handled correctly. Specifically, it might be that the dirty bit is not set during write commands.

I propose a possible way to reproduce the error: I try to add assertion to detect if the dirty bit hold true after every write command. If my hypothesis is true, the assertion statement would generate an error.

After fixed it, I would re-run the program to see if my assertion error goes away.

Table of Content