You are on page 1of 10

Computer Architecture

Report

Author: Emil Sadigov CS2


 
April 9, 2020 
 
 
 
 
 
 
 
 
 
Practical Session 4 : Coding

Types and Expressions

​ 1)​ Let us consider the code on the right [code]. The


Q
expected output is "z = 4.905000". What is the output
value? Why ? Find a minimal modification such that
this code produces the expected output. Then change
the type of z to int : deduce how the conversion from
float to integer works.

Answer​:

Here we got output z = 0.000000 , because dividing integer by integer cannot


give a float number in output , it will always give integer. So in our case ,
dividing 1 by 2 ​ ​gives us 0​ , as result we have z = 0 * g * t * t = 0. Then why our
answer is float ?(0.000000) Answer is in declaration of z , ​it is float​.
So , in order to get expected output , code can be modified in different ways ,
but I will propose 2 solutions based on 2 methods.

1. We can​ convert 1 or/and 2 to float​ simply adding dot(1. or 2.) , it works


because then it will be displayed as 1.0. Also it can be done using casts -
(float) see examples:

​Output: z = 4.905000
2. Second method is based on C promotion , so while multiplying type is
converted to appropriate one , in order to get expected output we simply
change position of 1/2 and ​put it after g(which is float)​ so it will be
converted to float while computation.

Last question was , change type of z to int. Then output is 4. Because


changing type converts z to integer after computation , processor gets 4.905000
and converts it to integer by rounding it to lower and outputs 4 , we get loss of
precision.

Q2)​ Let us consider the code on the right . The expected


output is "Normal". What is the output value? Why ? Find a
modification such that this code produces the expected output.

Answer​:

Here output is “Strange” , ​because sizeof() function returns value of type


unsigned int​. And while comparing unsigned int with another value , this value
by default is converted to unsigned , -1 in terms of unsigned is a max number ,
so if() statement is true and we got “Strange” message
Solution is using type casting , in order to convert return value of sizeof() to int ,
see code:​

​Output: “Normal”

Q3)​ Let us consider the code on the right


(note that long long is a 64-bit signed integer
type). Are the output values the same? Why?
Find a modification (different than computing
p1) such that this code produces the expected
output.

Output: p1 = 2500000000000000
p2 = -1794967296000000

Answer​:

I already mentioned it in the first question(answer part) ,​ ​this error appears


because of operand promotion​ ​, calculations can be done only with values of the

same type , hence types are converted by processor to the most precise one in
calculation . In our example p2 gives us a strangely large and negative number ,
because the processor firstly multiplies x which is an integer of big value
(50000) by x, here we get​ ​integer overflow​. Integer overflow - trying to put in
place into computer memory an integer which is too large , it gives big negative
random numbers.
1. Solution is to multiply integer “x” by long long “a” and after that by
integer “x” , because they will be promoted to the “long long” and as
result overflowing was avoided. So all we need to do is add parentheses ,
see code:

Output: p1 = 2500000000000000
p2 = 2500000000000000
Now it works properly.

2. Another method is using casting - (long long) which helps in avoiding


overflowing , see code:

Output: p1 = 2500000000000000
p2 = 2500000000000000

Q4)​ Let us consider the code on the right . Does this


program behave in the same way as the previous code
before modification? Why, while the calculation x * x is not
supposed to fit in a char?
Answer​:

Here we have char , ​which is promoted to int in computations automatically,​


that is why our program runs properly and we avoid overflow. ​This is done
because int is assumed to be the most efficient integral data type. Even though
char can store up to 255 , while computation in our example multiplying 50 by
50 having 2500 does not give us overflow , because as it was mentioned it is
promoted to int.
Exercise session 4: Cache Memory

2. Data Locality

1. Give examples of spatial locality in this program.


2. Give examples of temporal locality in this program.

Firstly , What is Data Locality?


Locality of reference​ - tendency of the processor to access the same set of
memory over a short period of time. Main purpose is to save time - if we access
the same memory set several times or call nearby data, it will be a loss of time
to access it from main memory , that is why it is stored in cache.
Temporal locality​ - if an information was referenced , then most likely same
information will be accessed in near future again
Spatial locality​ - if an information was referenced at particular time , then most
likely nearby memory locations will be accessed soon.
Answer​:
In our example we can recognize several examples of temporal locality:

N is defined to be 10 , so the program referenced memory for N , and it is called


several times in​ for loop to compare with i ,​ ​ which is also defined in for loop
then accessed several times to increase its value , printing it in the terminal and
to compare with N.​ These all are examples of temporal locality , because the
same memory addresses were accessed in a short period of time.

Here we can see an array of chars, it is adjacent memory cells accessed in


memory sequentially. To print the message “First integer numbers”, the
program accesses ​message[​0​]​ which is “F” , then ​message[​1​]​ - “i” and so on ,
which represents spatial locality.

3.1 Organization

Let us consider a 32KB cache memory:


1. How many blocks can it hold if the block size is 32, 64 or 128 bytes?
2. If a block contains 64 bytes and a memory address is 24 bits long, explain
how the address is decomposed (in tag, set index and offset) in the case of
a fully-associative cache, a direct-mapped cache and finally a 4-way
set-associative cache.

Data block​ is cache’s unit of information


- it is composed of bytes with consecutive addresses
- which are uniquely identified by the common part of the addresses of the
bytes in the block , called ​tag
1. To determine this firstly​ ​data was converted to “2 in power” format:

32KB = 2​15 128 bytes = 2​7


32 bytes = 2​5 64 bytes = 2​6

Now dividing cache memory by size of block , and taking power we get number
of blocks:
Answer:

if 32 → 2 15 ÷ 2 5 = 2 10 , so 10 blocks
if 64 → 2 15 ÷ 2 6 = 2 9 , so 9 blocks
if 128 → 2 15 ÷ 2 7 = 2 8 , so 8 blocks

2. ​Data​: 32KB cache memory


64-byte block
24 bits long memory address

a)​Fully-associative
- Firstly we find offset which can be calculated by formula -
log​2​(block-size):

of f set = log 2 64 = 6 bit

- As it is fully-associative there is only one set , so set index is 0


in order to find tag we simply subtract offset from memory address which
is 24 bit:

tag = 24 − 6 = 18 bit

Answer​: offset = 6 bit , tag = 18 bit and set index = 0.


b)​ Direct-mapped
- for first step we have same value because size of block is same, so:
of f set = 6 bit

- As it is direct-mapped - each set contains one block , we can say that


number of sets and blocks are equal:

set = 2 15 ÷ 2 6 = 2 9 = 9 bit

- in order to find tag we again do subtraction:

tag = 24 − 6 − 9 = 9 bit

Answer​: offset = 6 bit , tag = 9 bit and set index = 9.

c)​ 4-way set-associative cache

- for first step we have same value:


of f set = 6 bit

- Here each set contains 4 blocks , so we should divide set index by 2​2 ​:

set = 2 15 ÷ 2 6 ÷ 2 2 = 2 7 = 7 bit

- And finally we find tag:

tag = 24 − 7 − 6 = 11 bit

Answer​: offset = 6 bit , tag =11 bit and set index = 7.

You might also like