CS106X Handout

CS106X Handout

CS107 Cynthia Lee Winter 2017 CS107 Final Exam (Practice #1) You have 3 hours to complete all problems. You don’t need to #include any libraries, and you needn’t use assert to guard against any errors. Understand that the majority of points are awarded for concepts taught in CS107, and not prior classes. You don’t get many points for for-loop syntax, but you certainly get points for proper use of &, *, and the low-level C functions introduced in the course. Problem Points Score Grader 1. Number 5 representation 2. Generics, pointers, and 10 CVector 3. Assembly and 17 optimizations 4. Build process 10 5. Heap allocator 18 6. Cache design 6 TOTAL 66 Problem 1: Number Representation (5pts) (a) (2pts) Write the minifloat representation of the decimal value -5/8. Recall that minifloat is a (made-up) 8-bit floating point format with 1 sign bit, 4 exponent bits, and 3 mantissa bits. Write your answer as a bit pattern in these boxes: fraction = Scratch work space: (b) (1pt) What is the binary equivalent of the following hexadecimal number? 0xCAFE0 (Write your answer in the box.) (c) (2pt) What does the following code print? (Write your answer in the box.) unsigned int moana = 0xFFFFFFCC; int maui = (int)moana; printf("%d", maui); Problem 2: Generics, pointers, and CVector (10 points) (a) (4pts) You would like to use a CVector to hold your CS107 assignment grade information. Each entry in the CVector will be a struct that holds information for one assignment. The struct is defined below, and we also show an excerpt of code that calls cvec_create: typedef struct { int num; // assignment number, e.g., 4 for assign4 double score; // your score as pct, e,g., 0.92 for 46/50 char *letter_grade;// your letter grade as a string, e.g., "A-" } assignT; // excerpt of code where cvec_create is called CVector *grades = cvec_create(sizeof(assignT), 8, assign_cleanup); // end excerpt Write a callback function that can be passed to cvec_create that will appropriately clean up memory for your grades vector so there will be no leaks. Assume that any memory associated that could possibly need freeing in this callback should be freed in this callback. In particular, assume the letter grade strings were created using strdup. void assign_cleanup(void *assign) { } [For parts (b), (c)] Recall our generic “swap” function from class (reproduced below). It is used to make two values trade places in memory, and is commonly used in sorting arrays. There’s a right way to call this swap function in normal circumstances, but we’re asking you to use it a bit “creatively” to achieve particular results. Note: what matters for the correctness of these results is that the output if you ran this “for (int i = 0; i < 5; i++) printf("%d %d ", ptr1[i], ptr2[i]);” after the call to swap_any matches what it would be for the “after” diagram shown. void swap_any(void *a, void *b, size_t sz) { char tmp[sz]; memcpy(tmp, a, sz); memcpy(a, b, sz); memcpy(b, tmp, sz); } (b) (3pts) Complete the mixup1 function to create this before & after result. Your solution must consist of ONLY completing the arguments of the one call to swap_any, as shown. Before: After: ptr1 ptr2 ptr1 ptr2 void mixup1() { int *ptr1 = malloc(5 * sizeof(int)); int *ptr2 = malloc(5 * sizeof(int)); 1 6 8 6 for (int i = 1; i <= 5; i++) { ptr1[i-1] = i; 2 7 9 7 ptr2[i-1] = i + 5; 8 10 3 1 } 4 9 4 2 swap_any(____________________________, 5 10 5 3 ____________________________, ___________________________); } (c) (3pts) Complete the mixup2 function to create this before & after result. Your solution must consist of ONLY completing the arguments of the one call to swap_any, as shown. In this case (part (c)), the third argument should not be edited other than to specify a single argument (that should be a standard type) to sizeof(). Before: After: ptr1 ptr2 ptr1 ptr2 void mixup2() { int *ptr1 = malloc(5 * sizeof(int)); int *ptr2 = malloc(5 * sizeof(int)); for (int i = 1; i <= 5; i++) { 1 6 6 1 ptr1[i-1] = i; 2 7 7 2 ptr2[i-1] = i + 5; 3 8 8 3 } 4 9 9 4 swap_any(____________________________, 5 10 10 5 ____________________________, sizeof(_________)); } Problem 3: Assembly and optimizations (17 points) Consider the following x86-64 code output by gcc using the settings we use for this class (-Og): <ham>: mov (%rdi),%eax lea (%rax,%rax,2),%esi add %esi,%esi mov $0x0,%ecx imul $0x31,%esi jmp L1 L3: lea (%rcx,%rax,1),%edx movslq %edx,%rdx mov %esi,(%rdi,%rdx,4) add $0x2,%eax jmp L2 L4: mov %ecx,%eax L2: cmp $0x9,%eax jle L3 add $0x3,%ecx L1: cmp $0x9,%ecx jle L4 mov $0xa,%eax retq Refer back to this code to answer the questions in parts (a)-(d), on the following pages. (a) (8pts) Fill in the C code below so that it is consistent with the above x86-64 code. Your C code should fit the blanks as shown, so do not try to squeeze in additional lines or otherwise circumvent this (this may mean slightly adjusting the syntax or style of your initial decoding guess to an equivalent version that fits). Your C code should not include any casting. Note that with the compiler set to –Og, some optimization has been performed. One thing you’ll notice right away is that gcc chose not to create an actual eliza array, but instead kept track of its values in other ways. We will ask about optimizations in more detail in later parts of this question. int ham(int *burr) { int eliza[4]; eliza[0] = 7; eliza[1] = 7; eliza[2] = 1; eliza[3] = _____________ * burr[0]; // part (b) for (int i = 0; i < ___________; i+=___________) { for (int j = ___________; j < ___________; j+=___________) { burr[__________] = eliza[0] * eliza[1] * eliza[2] * eliza[3]; //(c) } } if (eliza[0] > eliza[1]) { // part (d) return 8; } if (burr[0] < burr[1] && burr[0] > burr[1]) { // part (d) return 9; } return ___________; } Here is a list of optimizations that we discussed in class. Use it to answer parts (b), (c). i. Constant folding ii. Common subexpression elimination iii. Dead code iv. Strength reduction v. Code motion vi. Tail recursion vii. Loop unrolling (b) (2pts) Refer back to the C code, on the line marked for part (b). It reads: eliza[3] = … * burr[0]; Which optimization from the list most closely relates to this implementation? ______ Name and explain the instruction(s) that implement this product, and explain why gcc would choose to do it that way. (c) (3pts) Refer back to the C code, on the line marked for part (c). It reads: burr[…] = eliza[0] * eliza[1] * eliza[2] * eliza[3]; Which two optimizations from the list most closely relate to when and how this product is calculated? ______ ______ Name and explain the instruction(s) that calculate this product off all the eliza terms: (d) (2pts) Refer back to the C code, on the two lines marked for part (d). (Two if statements.) Neither if statement appears in the assembly code at all, because they are “dead code.” However, the reasons they are considered dead code are slightly different in each case. Explain each case below: How does gcc know that the first if statement is dead code? How does gcc know that the second if statement is dead code? (e) (1pt) In class, we looked at the following simple array sum function, where the order of summing the elements of the array is dictated by the provided indexes array (it contains some permutation of the numbers [0, ..., n-1]): static int sum_fwd_ind(int a[], int n, int indexes[]) { int sum = 0; for (int i = 0; i < n; i++) sum += a[indexes[i]]; return sum; } We saw in class that, for large arrays, this function performs about 3 times faster when indexes is sorted in ascending order than when indexes is in random order. Explain why this can happen even though the code is the same. Problem 4: Build process (10 points) For this problem, you are presented with five small programs, along with the commands that in theory can be used to build and execute them. You should write something about each of the six programs, as follows: Assume we compile using: gcc –Wall –o prog prog.c, and attempt to run the prog executable (if one was generated) with three arguments, like this: “arg1 arg2 arg3”. If any warnings or errors are issued during the build process, you should identify which component(s) issue the warning(s) and/or error(s) by circling all applicable responses. If everything builds (with or without warning(s)) say what will happen when it is executed by circling a response. Remember that if any step gives an error, subsequent steps do not occur (so do not circle them for warnings/errors), and an executable is not produced (so circle “N/A” for the executable part). There is no need to provide an explanation, just circle. The programs aren’t intended to do anything meaningful, as they’re contrived to exercise your understanding of the build process and the C runtime. Note that when #include directives you might expect are NOT used in a program, that’s quite intentional! (a) (2pts) Consider the following program: int strcmp(const char *s1, const char *s2); int main(int argc, const char *argv[]) { return strcmp(argv[0], argv[1]); } Which component(s) complain with warning(s) and/or error(s)? (circle ALL that apply) Preprocessor Compiler Linker N/A (no warnings or errors) If an executable is produced, what happens when you run it? (circle ONE) NO crash MAY crash SURE crash N/A (earlier error) (b) (2pts) Consider the following program: #define PURPLE_RAIN return int main(int argc, const char *argv[]) { if (strlen(argv[0]) > strlen(argv[3])) PURPLE_RAIN argc; else PURPLE_RAIN argc + 1; } Which component(s) complain with warning(s) and/or error(s)? (circle ALL that apply) Preprocessor

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    16 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us