Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

For the following code loop: for (i=0; i<1000; i++) { if ((i mod 2)==0) { // Do

ID: 3799978 • Letter: F

Question

For the following code loop:

for (i=0; i<1000; i++)
{
   if ((i mod 2)==0)
   {
   // Do some stuff, no branches here
   }
}

a) The code results in at least two conditional branches. Using a one-bit predictor for branch prediction, what is the prediction accuracy for the loop and for the if statement? Assume the initial prediction is to take the branch.

b) Using the two-bit predictor shown by the finite state automaton below, what is the prediction accuracy for the loop and the if statement? Assume you start in state 00.

c) Would a correlation predictor help in this case?

00 Predict taken Predict not taken NT NT Predict taken T t NT Predict not taken

Explanation / Answer

Beyond the issues mentioned higher than, there square measure even machine issues that can't be solved in the slightest degree, even in essence, and even with unlimited time and area. we will prove mathematically that such issues exist. we'll concentrate on call issues wherever the goal is to calculate a Boolean result regarding some input, and that we can show that some call issues square measure undecidable by any rule.

Undecidability of the halting drawback

An example of such a choice drawback is that the halting drawback: will a given program terminate once run on a given input? we'll see that the halting problem is undecidable generally. That is, there doesn't exist associate degree rule that forever halts and answers the question properly for all programs and inputs.

We have seen in previous lectures and from the programming assignments that programs are often portrayed as a knowledge structure intrinsically as abstract syntax tree or bytecode. allow us to assume there's a category Program which will be wont to represent programs.

We want to grasp whether or not we will implement a way with the subsequent specification:

/** Returns true if the given program p terminates once given inp as input,
* otherwise returns false. */
boolean terminates(Program p, Object inp);
That is, for each p and input inp, it ought to with success come back either true or false betting on whether or not the program portrayed by p halts on input inp. Note that though terminates is simply one technique, it's allowed to use as several different categories and ways because it likes. we've got the total power of Java at our disposal.

For simplicity allow us to think about solely Java programs that implement a choice drawback and have the subsequent form:

class P {
Boolean main(Object inp)
}
If p is associate degree instance of Program that represents the Java program P, then terminates(p,inp) ought to come back true or false according as P.main(inp) halts or doesn't halt, severally.

The method main is allowed to use different categories and ways. However, we'll solely think about programs that receive no input from and send no output to the skin surroundings. {the solely|the sole} input to the program is inp and also the only output is that the Boolean results of main. If we will not confirm whether or not such easy programs terminate, then in fact we've got no hope of decisive whether or not additional complicated programs do.

We have seen that it's attainable to write down associate degree interpreter for a artificial language. associate degree interpreter for programs like P (as coded by the Program object p) are often written with the subsequent signature:

/** Simulate the execution of p on input inp, returning
* a similar result as p would. If p would fail to terminate on
* this input, therefore will interpret(p, inp).
*/
boolean interpret(Program p, Object inp);
In different words, interpret(p, inp) provides precisely the same result as P.main(inp).

Now think about the subsequent program.

1 category H {
2 Boolean main(Object inp) {
3 if (!(inp instanceof Program)) come back false;
4 Program p = (Program)inp;
5 if (!terminates(p, p)) come back true;
6 come back !interpret(p, p);
7 }
8 }
Note that H.main terminates on any input inp, as a result of the sole chance for nontermination is in line vi within the decision to interpret(p, p), however we've got already secured that this can terminate by the decision to terminates(p, p) in line five. thus H.main(inp) forever returns either true or false.

But currently let h be associate degree instance of Program representing H, and think about what happens once we run H.main(h). As argued higher than, this should terminate. The program doesn't come back in line three and also the solid succeeds in line four as a result of h is associate degree instance of Program. The program doesn't come back in line five as a result of that might solely happen if terminates(h, h) came false, which might solely happen if H.main(h) didn't terminate, however it will. therefore we have a tendency to get all the thanks to line vi. however currently observe that in line vi,

H.main(h) returns true interpret(h, h) returns false H.main(h) returns false.

This is a contradiction!

This contradiction implies that our original assumption should be wrong. we all know that we have a tendency to cannot implement each terminates and interpret. however we all know a way to implement interpreters for programming languages (including Java) in Java; we have a tendency to did it for a far easier language in Assignment five, however the principle is that the same. therefore the inaccurate assumption was that we have a tendency to might decide termination. The procedure terminates cannot exist.

The conclusion is that there square measure some helpful things that square measure merely not estimable by any rule.

Implications for program analysis

This result has some sensible implications. especially, many alternative program analyses aside from termination can't be set exactly. If they may be, then the halting drawback would be decidable, and that we have simply shown that it's not. As a result, these program analyses should be conservative, giving answers “true”, “false” or “not sure”. kind checking is one example. Ideally a kind checker would tell you at compile time whether or not there was any input that would cause a program to own a kind error at run time. however we have a tendency to might apply such a kind checker to code just like the following:

while (...) {
// complicated computation
}
int x = thirty two + "hi";
This code encompasses a dynamic kind error if associate degreed on condition that there's an input that causes the whi