MIPS Programming Practice Midterm 1 Solutions, Exams of Computer Architecture and Organization

Solutions to practice midterm 1 of the cs232 fall 2006 course, including c to mips translation, debugging mips code, cpu performance optimization, and conceptual questions.

Typology: Exams

Pre 2010

Uploaded on 03/16/2009

koofers-user-925
koofers-user-925 🇺🇸

5

(1)

10 documents

1 / 5

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
CS232 Fall 2006 Practice Midterm 1
1. C to MIPS translation:
Translate the following C function into MIPS. Assume that the functions getPivot and
insertionSort have already been translated for you. Be sure to follow all calling con-
ventions!
void quickSort(int array[], int n) { // n = length of array
int p;
if(n <= 5) {
insertionSort(array, n);
}
else {
p = getPivot(array, n); // assume p > 0
quickSort(array, p);
quickSort(array + p, n - p);
}
}
1
pf3
pf4
pf5

Partial preview of the text

Download MIPS Programming Practice Midterm 1 Solutions and more Exams Computer Architecture and Organization in PDF only on Docsity!

  1. C to MIPS translation:

Translate the following C function into MIPS. Assume that the functions getPivot and insertionSort have already been translated for you. Be sure to follow all calling con- ventions!

void quickSort(int array[], int n) { // n = length of array int p; if(n <= 5) { insertionSort(array, n); } else { p = getPivot(array, n); // assume p > 0 quickSort(array, p); quickSort(array + p, n - p); } }

  1. Debugging MIPS:

The following recursive C function getNode returns a pointer to the nth^ node of a linked- list. Each node of the list contains an int data field and a next field that is a pointer to the next node in the list. The inputs to the function are n and head (a pointer to the first node in the list).

struct node{ int data; node* next; }

node* getNode(int n, node* head) { if(n <= 0 || head == 0) // 0 == NULL pointer return 0; if(n == 1) return head; // current pointer return getNode(n-1, (*head).next); }

An incorrect MIPS translation of getNode is given below:

getNode: addi $sp, $sp, 4 # line 1 sw $ra, 0($sp) # line 2 bgt $a0, $zero, positive # line 3 bne $a1, $zero, positive # line 4 li $v0, 0 # line 5 positive: bne $a0, 1, recursive # line 6 li $v0, 1 # line 7 jr $ra # line 8 recursive: addi $a0, $a0, -1 # line 9 lw $s0, 0($a1) # line 10 add $s0, $s0, 4 # line 11 move $a1, $s0 # line 12 jal getNode # line 13 addi $sp, $sp, 4 # line 14 lw $ra, 0($sp) # line 15 jr $ra # line 16

Identify and correct all errors (including violations of calling conventions) in the above code. You may rewrite the code, or simply indicate the changes that you need to make.

Errors Corrected code

  1. Conceptual questions:

(a) Describe how to write an exception handler for memory address misalignment that gives the MIPS processor the ability to load and store words from memory addresses that are not multiples of four. (b) Segment A of a program accounts for 30% of the running time and can be sped by a factor of 3. Segment B of the same program accounts for 10% of the running time and can (independently) be sped up by a facor of 5. How much faster would the new program be if both optimizations were performed? (c) In some languages, it is possible to pass a function f as an argument to another function g. By varying the function f , different “versions” of g can be implemented without writing new code. 1 Explain how something similar can be done in MIPS by using a pointer to the function being passed as an argument. Describe the MIPS code needed to pass such a function as an argument, and describe the MIPS code required to invoke such a function. (d) For the following chunk of code, assign registers to hold the expressions and sub- expressions required to execute the code. You may only use registers $t0–$t3 (the other registers are in used by other parts of the code). If it is unnecessary to calculate a particular sub-expression, simply do not assign it a register.

Code:

avg[0] = array[0]; avg[1] = (array[0] + array[1]) / 2; avg[2] = (array[0] + array[1] + array[2]) / 3;

Expressions:

&avg &array &avg[0] &array[0] array[0] &avg[1] &array[0] &array[1] (array[0] + array[1]) (array[0] + array[1]) / 2 &avg[2] &array[0] &array[1] &array[2] (array[0] + array[1]) (array[0] + array[1] + array[2]) (array[0] + array[1] + array[2]) / 3

(^1) As an example, the quickSort function in Problem 1 could have another argument sort that specifies the sorting function to be used when the array is small, i.e. ≤ 5 elements. The same quickSort function could then be called with insertionSort or bubbleSort functions as arguments, producing distinct versions of the QuickSort algorithm.

These are some of the most common MIPS instructions and pseudo-instructions, and should be all you need. However, you are free to use any valid MIPS instructions or pseudo-instruction in your programs. The second source operand of the arithmetic, logical, and branch instructions may be a constant.

Category Example Instruction Meaning Arithmetic add $t0, $t1, $t2 $t0 = $t1 + $t sub $t0, $t1, $t2 $t0 = $t1 - $t addi $t0, $t1, 100 $t0 = $t1 + 100 mul $t0, $t1, $t2 $t0 = $t1 × $t div $t0, $t1, $t2 $t0 = $t1 / $t Logical and $t0, $t1, $t2 $t0 = $t1 & $t2 (Logical AND) or $t0, $t1, $t2 $t0 = $t1 | $t2 (Logical OR) sll $t0, $t1, $t2 $t0 = $t1 << $t2 (Shift Left Logical) srl $t0, $t1, $t2 $t0 = $t1 >> $t2 (Shift Right Logical) sra $t0, $t1, $t2 $t0 = $t1 >> $t2 (Shift Right Arithmetic) Register Setting move $t0, $t1 $t0 = $t li $t0, 100 $t0 = 100 Data Transfer lw $t0, 100($t1) $t0 = Mem[100 + $t1] 4 bytes lb $t0, 100($t1) $t0 = Mem[100 + $t1] 1 byte sw $t0, 100($t1) Mem[100 + $t1] = $t0 4 bytes sb $t0, 100($t1) Mem[100 + $t1] = $t0 1 byte Branch beq $t0, $t1, Label if ($t0 = $t1) goto Label bne $t0, $t1, Label if ($t0 6 = $t1) goto Label bge $t0, $t1, Label if ($t0 ≥ $t1) goto Label bgt $t0, $t1, Label if ($t0 > $t1) goto Label ble $t0, $t1, Label if ($t0 ≤ $t1) goto Label blt $t0, $t1, Label if ($t0 < $t1) goto Label Set slt $t0, $t1, $t2 if ($t1 < $t2) then $t0 = 1 else $t0 = 0 slti $t0, $t1, 100 if ($t1 < 100) then $t0 = 1 else $t0 = 0 Jump j Label goto Label jr $ra goto address in $ra jal Label $ra = PC + 4; goto Label

Register Conventions: The caller is responsible for saving any of the following registers that it needs, before invoking a function. $t0-$t9 $a0-$a3 $v0-$v The callee is responsible for saving and restoring any of the following registers that it uses. $s0-$s7 $ra

Performance: Formula for computing the CPU Time of a program P running on a machine X: CPU TimeX,P = Number of instructions executedP × CPIX,P × Clock Cycle TimeX

CPI is the average number of clock cycles per instruction: CPI = Number of Cycles Needed/Number of Instructions Executed

Speedup is a metric for relative performance of 2 executions: Speedup = (^) Performance before ImprovementPerformance after Improvement = Execution time before ImprovementExecution time after Improvement

Amdahl’s Law: Execution Time after Improvement = Time affected by ImprovementAmount of Improvement +Time unaffected by improvement