Final

Download as pdf or txt
Download as pdf or txt
You are on page 1of 4

219222/223 (Section 450) Introduction to Computer Systems

Final Exam
12 May 2021

▪ This is an open everything exam. You are allowed to do the exam from anywhere
and use the Internet for researching. However, you have to submit the answer by the
deadline and you cannot communicate with anyone except the instructor.
▪ Stealing answer from the Internet without any citation is grounds for cheating. So,
reference your sources.
▪ All your answer must go in to a pdf file called StudentID_Firstname_final_ans.pdf,
where StudentID is your KU ID and Firstname is your given name

1. (30) Cache

1.1. (12) Given that our system uses 48-bit addresses:

For the following cache configuration, calculate the number of bits required for the offset,
index, and tag fields. Also, show a diagram indicating where those bits are located in a 48-bit
address.

A. 128 KiB direct-mapped with a block size of 128 bytes


B. 128 KiB 4-way set associative with a block size of 128 bytes
C. 256 KiB direct-mapped with a block size of 128 bytes
D. 256 KiB 8-way set associative with a block size of 128 bytes

1.2. (8) Given the following linked list for integer key elements

and the code to search for a particular key below

int search(struct node *head, int key) {


while (head != NULL) {
if (head->num == key) {
return 1;
}
head = head->next;
}
return 0;
}


Explain if it is possible to calculate the miss rate for this code given that you have a directed-
mapped cache of size 1 KiB with block size of 16 bytes. If so, show your calculation, if not
give an argument why not.

1
1.3. (10) Given the snippets of code below

# define N 64

int a[N * N];


int b[N * N];
int i, j;
int sum1 = 0, sum2 = 0;
for (i = 0; i < N; i++)
for (j = 0; j < N; j++) {
sum1 += a[i*N + j];
sum2 += b[i*N + j];
}

Let this code run on a CPU with 16 KiB direct-mapped cache whose block size is 128 bytes,
calculate the approximate miss rates, focusing exclusively on the accesses to the ‘a’ and ‘b’
arrays. You must show your work to receive credit. Note that an int array element occupies 4
bytes of memory.

2. (10) General operating systems (OS) questions

2.1. (2) What are the pros and cons of computer systems with and without OS?

2.2. (2) Why are modern computers less secured than earlier computers?

2.3. (2) Why are some of the disadvantages of having a thin-waste stack?

2.4. (2) Why does the CPU need to be virtualized?

2.5. (2) Why do we have only a handful of OS (e.g. Windows, Linux) but many more
applications?

3. (40) Process and thread APIs

3.1. (20) Consider the following code: (https://pastebin.com/z3LQmD9S)

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#include "common.h"
#include "common_threads.h"

volatile int counter = 0; // shared global variable

void *mythread(void *arg)


{
char *letter = arg;
int i; // stack (private per thread)
printf("%s: begin [addr of i: %p]\n", letter, &i);
counter = counter + 1; // shared: only one
printf("%s: done\n", letter);
return NULL;
}

void *mythread2(void *arg)

2
{
char *letter = arg;
int i; // stack (private per thread)
printf("%s: begin [addr of i: %p]\n", letter, &i);
counter = counter - 1; // shared: only one
printf("%s: done\n", letter);
return NULL;
}

int main(int argc, char *argv[])


{

pthread_t p1, p2, p3, p4;


printf("main: begin [counter = %d] [%x]\n", counter, (unsigned
int)&counter);
Pthread_create(&p1, NULL, mythread, "T1");
Pthread_create(&p2, NULL, mythread, "T2");
Pthread_create(&p3, NULL, mythread2, "T3");
Pthread_create(&p4, NULL, mythread2, "T4");
// join waits for the threads to finish
Pthread_join(p1, NULL);
Pthread_join(p2, NULL);
Pthread_join(p3, NULL);
Pthread_join(p4, NULL);
printf("main: done [counter: %d]\n", counter);
return 0;
}

When it finishes the execution, explain if it is possible to generate the following final print:

A) main: done [counter: 0]


B) main: done [counter: 2]
C) main: done [counter: -1]
D) main: done [counter: 3]

No explanation = no scores

3.2. (20) Consider the following code

void main() {
printf(“Start\n”);
if (fork() == 0) {
printf(“One\n”);
if (fork() != 0) {
printf(“Two\n”);
if (fork() != 0) {
printf(“Three\n”);
}
}
}
printf(“End\n”);
}

When it finishes the execution, explain how many possible outcomes can be generated. You
must show your work to receive credit. List 3 sample possible outcomes.

No explanation = no scores

3
(Hint: you have to construct a correct process graph and analyze at all the possible partial
orderings)

4. (20) Synchronization

4.1. (5) Why is it unwise to create your own mutual exclusion solution instead of using lock
primitives?

4.2. (15) The following snippet of code shows an incorrect solution to the critical section
problem:

Proof that this solution is incorrect by showing either cases for safety of liveness violations.

Submission:
• Submit the file StudentID_Firstname_final_ans.pdf to the course’s Google
Classroom before the deadline. StudentID is your KU ID and Firstname is your given
name.

You might also like