Wednesday, January 19, 2011

Sorting

Quicksort
Divide and Conquer algorithm for sorting A[p .. r]
practically runs on average case Th(n lg n) and very small hidden constant factor
in place sorting algorithm
not stable
widely used and considered best for use

Divide: choose middle element such that all elements to right are greater and to left are smaller
Conquer sort the left and right subarray recursively
Combine once subarrays are sorted in place the list is in sorted order.

Divide
main job in divide step is to get the pivot element to right of which elements are greater and left elements smaller
Partition(A,p,r)
Pivot choice: we choose last element as pivot x=A[r]
we maintain 4 partitions
first partition keeps elements no greater than x
second keeps elements greater than x
third partition is for unprocessed elements
fourth partition is the x, pivot

j is used to process each element from p to r-1
we are interested in this three conditions
first partition(index p to i) will have all the elements <= x
second partition (index i+1 to j) will have all elements > x
and third will have x

Partition(A,p,r) Algorithm
get the last element as pivot x
set i to p-1
for each element j from  p to r-1
if current elment A[j] <= pivot x
  //then it belongs to first partition replace first element in partition 2 with this element
  i=i+1     //points to first element in second partition
  exchange A[i] to A[j]  // exchange with this current element
  // for first element is less than x than we exchange it with itself because of conditions above
At last we replace the  first index in second partition with pivot to get pivot in middle of two subarray

Running time of partition algorithm is O(n) because we parse all n-1  elements and perform some constant time operations

Performance of Quicksort
running time depends on whether partitioning is balanced or unbalanced
If balanced partition it behaves like merge sort
If unbalanced partition them as slow as insertion sort (O(n^2))

Worst case partitioning
when sub problem is divided in to size n-1 and 0
assuming same unbalanced partition at each level
T(n) = T(n-1) + T(0) + Th(n)  //Th(n) for partition
Tn =Th(n^2)

This case occurs when list is already sorted, in which insertion gives time of O(n).

Best-case Partitioning
when partition divides list even size, that is, floor(n/2) and n/2-1
T(n) <= 2T(n/2) + Th(n)
T(n) =O(nlogn)

Average case
whenever partition yields constant proportionality we get the running time of O(nlogn)

Space complexity (O(lg n) in the worst case can be achieved)
Partitioning is in place O(1)
After partition element are sorted requiring recursive call taking most O(lg n) space

Selection based pivoting
selection algorithms can be used to choose best pivot to partition list
selection algorithm worst case is O(n) so we can use it to find best pivot at each stage and get worst case of O(nlogn) but this variant is slower compared to normal in average case

Problem Show that minimum depth of a leaf in recursion tree of quicksort split of 1-a and a (0<=1/2) is
-lg n/log a and max is -lg n/lg 1-a
Solution we have to look for path which is largest or has maximum depth
splits of larger size takes more number of further splits to reduce to base case so 1- a side split should have more depth because a < 1-a
at each level number of elements n is reduced by a that is (1-a)^i*n at i level
for leaf (1-a)^i*n =1
(1-a)^i =1/n
i lg (1-a) = -lg n
i = -lg n /lg(1-a)

similarly for the minimum depth we look for a splits
a^i*n=1
i=-lg n/lg a

Problem What happens in case of all duplicates in list for above algorithm
Solution we look at the partition algorithm, what happens in case of same values of pivot and current element j

if A[j] <=x then we swap that with first element in second partition i+1 index
this happens for all the elements giving at last, same list as original with pivot at original position only and i and j pointing to index before r.
so it divides the list in n-1 and 0, worst case scenario of quicksort

Problem Show that running time of quicksort can be improved by taking advantage of insertion sort fast running time for nearly sorted list, running time O(nk + nlg(n/k)) when  insertion sort is called when subarray size is<=k
Solution
recursion stops when n/2^i =k  that is i=lg n/k
recursion takes in total O(n log n/k)
n is cost of each level and log n/k is depth of level
The resulting array is composed of k subarray of size n/k elements in each subarray are less than elements in the following subarray Insertion sort call on sublist of size k take Th(k^2) for worst case to sort n/k such list would take  n/k*Th(k^2) = Th(nk)
O(nk + nlog n/k)
k should be chosen such that no bigger than lg n

Expected Running time

Merge Sort
also example of divide and conquer algorithms
Divide: list of elements is divided equally in two sublists of size n/2
Conquer: Sort the two sub list recursively
Combine: Merge the two sorted sublist to get the final sorted list

In case of quicksort we did actual work in Divide step to find the pivot with partition procedure here we do most of work in combine step to merge two sorted lists

Merge(A,p,q,r)
merge sorted subarray A[p ..q] and A[q+1 ..r] and give single list of sorted sequence
In merge procedure we compare the first elements of each list and check for smallest between two then place that in new list similarly we check until one of the list goes empty at that point we just add the remaining elements in other list to final list
we can see the number of comparison when list1 is of length L1 and list2 of length L2 can be at most L1+L2-1
so we can say for merge procedure time complexity should be Th(n) where L1=L2~=n/2

In case of Merge procedure we include sentinel element at end which makes the comparisons uniform without need to check for empty list separately
The number of comparisons in this case would be equal to L1+L2, that is n in case of Merge procedure


Merge(A,p,q,r) Algorithm
create two arrays from element of A like L[p ...q-p+1] and L[r-q+1]
//with size one greater to include sentinel element(very large number in this case,say infinity)
//we merge the two list L and R in our original list A
 //parse the two list L and R with index i and j respectively
for each position k in list A[p ...r] 
// we know that in total we have to place r-p+1 elements and at each step we would insert one element in list //A, not necessarily in its correct position as in sorted sequence
if L[i] <= R[j]  //compare current element in each list
  A[k] = L[i]  // at each step A gets the small of the two lists
  i=i+1  //compare the next element in list L with current in R
else
A[k] = R[j]
j=j+1


At start iteration k of the loop Array A contains elements from index p to k-1 as smallest of the two list L and R that is k-p elements

Running time of Merge Procedure
populating the list L and R takes time Th(n1+n2) =Th(n)
looping for each index in A takes time Th(n)
so total running time is Th(n)

Merge sort Algorithm
Merge-sort(A,p,r)
if p < r // when p>=r there is single element and its already sorted
find middle index q = floor(p+r/2)
Merge-sort(A,p,q)
Merge-sort(A,q+1,r)
Merge(A,p,q,r)

Running time of Merge sort
Divide step takes Th(1) time, finding the middle index
Conquer step if T(n) be time for complete sorting of n elements than conquer step would take 2T(n/2)
Combine step is Merge procedure which takes Th(n)
T(n) = 2T(n/2) + Th(n)
T(1) = Th(1)

T(n)= Th(n lg n)

Insertion sort

in place sorting algorithm
stable sorting
efficient algorithm for sorting small number of elements
Insertion-sort(A)
take each element in array A and find its correct position in elements before it
two partitions of the set
first partition contains sorted list of elements processed so far
second partition is elements not processed yet

At each step first partition contains sorted list of elements processed so far

Algorithm
for each elements from index 2 to length[A]
k=A[j]  //call current element key
//no insert this element in to its correct position in A[1] to A[j-1]
i = j-1
while i>0 and A[i] >key  // for each element greater than key shift it one position to right
  A[i+1] = A[i]
  i=i-1
when we find i such that  A[i] < key
we insert out key in position after that
A[i+1] = key

Running time of Insertion Sort
Worst case when we need to shift all elements at left by one position this case occurs when A[j] is less than all the elements in the first partition, this is case of list in decreasing order
O(n^2)

Average case
Average case time is also O(n^2)
but fastest algorithm for sorting small arrays

Best Case
array that is already sorted
during each iteration A[j] is compared with only its left element which is smaller than key so inner loop only runs once for each j
Th(n)

Selection sort
Selection-sort(A, p, r) // p: starting index; r: ending index
if p < r       
  then largest =  p  // call first element largest
  for i  =  p+1 to r   // linear search to find largest
 do if A[i] >= A[largest]
       then largest  = i

Exchange A[r] and A[largest]
selection-sort(A, p, r-1);

Divide: Select the largest element in the array, and then swap the largest element
and the last element. The selection process uses a linear search. Thus, the divide step
takes linear time.

Conquer: Sort the the first n − 1 elements recursively. This step takes T (n − 1) time.

Combine: Do nothing.

 Recurrence: T (n) = T (n − 1) + n

Median and order statistics

Instruction set and Addressing mode

Addressing Modes
Addressing mode are aspect of instruction set architecture. Defines how the instructions identifies the operand.

Immediate Addressing
  • operand is present in the instruction
  • typically number will be stored in 2's compliment form
  • no memory reference other that instruction fetch is needed to get operand
  • Limits the size of number with size of address field
  • ADD R4, #5
  • reg[R4] <--- reg[R4] + 5

Direct Addressing
  • Address field contains effective address of the operand
  • EA = A
  • Single memory reference to get operand and no special calculations involved
  • Limited address space
  • ADD R4, 3000
  • reg[R4] <------ reg[R4] + mem[3000]

Indirect Addressing
  • with direct lenght of address field is usually less than word limiting the address range
  • address field refers to address of word in the memory which in turn contains the full length address of operand
  • two memory reference
  • ADD R4, 3000
  • reg[R4] <------ reg[R4] + mem[mem[3000]]
  • number of words that can be addressed has increased but number of different effective address that may be referenced is still limited


Register Addressing
  • address field refers to register rather than main memory
  • only a small address field is needed as there are few registers
  • no memory reference
  • Limited address space
  • ADD R4,R3,R2
  • reg[R4] <--- reg[R3]+reg[R2]

Register indirect addressing
  • accessed using computed address
  • ADD R4,(R1)
  • reg[R4] <--- reg[R4] + mem[reg[R1]

Displacement Addressing
direct addressing + register indirect addressing
Effective address = A + content of register R

1)relative addressing
the implicitly referenced register is PC that is A is added to PC to get EA
effective address is displacement relative to address of the instruction
exploits concept of locality
A + PC

2)base register addressing
the referenced register contains a memory address and address field contains a displacement(usually unsigned)
A + mem[mem[R]]
exploits locality of reference

3)Indexing
A= main memory address
R=displacement from that address

EA = A + content(R)
A lenght comparibly large than base register addressing

Auto indexing
index register, that is R displacement register, are used in iterative task so need to increment and decrement to address arrays or memory
automatically done part of same instruction cycle

EA = A + content(R)
R = R + 1

Post indexing
indirect addressing +  indexing
EA = content of A + content of R

preindexing EA = contents of (A + content (R))


Problem address stored in PC=X1 Instruction in X1 has addre ss part X2.The operands needed to execute the instruction is stored in memory word with address X2 An indext register contains the value X4 what is relationship between this when addressing mode is
1)direct
X3=X2

2)indirect
X2 should contain address of X3
that is content(X2) =X3
3)PC relative
X3= PC + displacement +1
X3=X1+X2+1
4)indexing
X3=X2 + index
X3=X2+X4

Problem If current instruction is 256028 in decimal and each instruction is 3 byte. offset is -31 find EA PC relative addressing
Solution
EA for pc address = next instruction address + offset(signed number)
next instruction address =  256028+3
EA = 256031 - 31 = 256000

EA for pc address = next instruction address + offset(signed number)

Problem A pC relative mode branch instruction is stored in memory at address 620 The branch is made to location 530 The address field in instruction is 10bit long
What is binary value in instruction
Solution Assuming offset is stored in 2's compliment because it should be signed number it can be negative for branch before and positive for branch after

EA for pc address = next instruction address + offset(signed number)

next instruction address (assuming one instruction per address) = 621
EA we have been given as 530 that is it branches to this address
so 530 - 621 = offset
offset = -91
two's compliment of -91 = 1110100101

Problem how many memory reference when it fetches and executes indirect address mode instruction is
a)computation with single operand
1 for instruction fetch+ 2 memory  reference for indirect address = 3
b)branch instruction
does not need to fetch the operand here only operand reference needed
1 for instruction fetch + 1 operand reference fetch = 2


Problem Instruction length is 16 bit.Operand specifics are 6 bits in length.
number of two operand instruction = K
number of zero operand instruction = L
number of 1 operand instruction = ?
Solution
Total number of bits is 16
total number of possible combinations is 2^16 of which we have to divide them as two operand instruction, one operand instruction and zero
For two operand instruction 12 bits are required for operand

K*2^12 + X*2^6 + L = 2^16Problem A 32bit ISA needs 100 opcodes 3 source operand 2 destination operand. source and destination operands are registers.maximum size of register file?
Solution 100 opcode needs 7 bits
5 operands(source+destination) have available 32-7  =25bits
each register can be addressed with 25/5 bits

 
Problem code to implement A = (B – C)*D in
1) three address instruction
SUB A B C
MPY A A D
2)two address instruction
MOV T1 B
SUB T1 C
MPY T1 D
MOV A T1
3)1 address instruction
LOAD B
SUB C
MPY D
STORE A
4)zero address
PUSH B
PUSH C
SUB
PUSH D
MPY
POP A

all instructions,data values  will be in memory and must be fetched from memory
fetching instruction like SUB A B C
requires 1 byte for opcode 2 byte for each address A B C. 7byte instruction of instruction to fetch

fetching data
each data value 2byte and during execution B and C datavalues will be fetched from the memory and A 2bytes will be written to memeory so total of 7+6 byte of memory traffic

 Unconditional branch
b label ;
assigns value of label to PC

Conditional branch
If condition is true PC is reset to label
If false branch instruction executes no-op
Zero test
beqz x,label   if x==0 then goto label
bnez x       if x!=0 then goto label
bltz less than zero blez if x less than or equal to zero 

Interrupt
Interrupt: depart from normal program sequence, also
called “exception”
Triggered not by instruction in the program itself
Types of interrupts:

– External interrupts: for example, from timing devices, I/O devices
– Internal interrupts: traps (invalid or erroneous use of an
instruction or data), eg. overflow, divide by zero, protection
violation
– Software interrupt: Generate an interrupt explicitly with an
instruction
An interrupt causes the normal program execution to halt and for the interrupt
service routine (ISR) to be executed.

Semiconductor memory
basic element memory cell
cell represent two stable state 1 and 0
capable of being written into, set state
three signals to each cell select(select particular cell) control(specify wether read or write) and read/write

DRAM
individual words of memory are directly accessed through wired -in address logic
RAM volatile(needs continous power, data donot persist on power cut) random access
DRAM stores data as charge on capacitor
capacitors have tendency to discharge so DRAM requires periodic charge refreshing
analogous device
SRAM
digital device uses flipflop logic gate config
DC applied
no refresh needed

comparision Dram and SRAM
both volatile and needs continous power.
DRAM simple small, more dense ,less expensive
DRAM requires refresh opeartion which is costly, favoured for large memory
SRAM generally faster, used as cache

Types of ROM
nonvolatile
can be read only

Problem write assembly code for
for (i=0; i<=100;i++)
 A[i] = B[i] + C;

R1= A[i]
R2=B[i]
R3=C
R4 = i*4

References
http://pages.cs.wisc.edu/~cs354-1/cs354/solutions/adv.hw.sol.html           // floating point and IEEE math
https://www.cis.upenn.edu/~cis501/

Monday, January 17, 2011

Memory Management - Linking, Loading, Virtual Memory

Loading and Linking

Linker 
A program consist of number of module these are linked to resolve any references between them
static libraries are linked at this time
Takes as input collection of modules are prepares a load module, each symbolic address within each module are changed relative to final load module and this final module is then loaded

Dynamic Linker
It is possible to defer some linkage functions
so load module will contain unresolved references to other programs
Load time Dynamic linking
load module is read into memory and any  unresolved references causes loader to find module, load it and alter the references to relative address
requires dynamic library to loader

Runtim dynamic linking
At the time when call is made to unresolved reference then it is brought in memory
these are shareable module so if its already in the memory linking is done to that.
DLL in windows are example


Loading

Loading is to move the program into memory where it has its associated PCB stack
Absolute loading
all absolute references, module always loaded at same memory location
assignment of addresses can be done by programmer or at compile time

Relative loading
memory address are relative to start of program
compiler or assembler does not produce absolute addresses instead relative
so module can be loaded in any memory location

Dynamic Runtime loading
Since swapping part of program is possible in virtual memory relative address wont work if next time part of program is allocated some other space in memory
so instead of calculating relative address at load time, calculations are deferred  until instruction is actually executed

Segmentation
user and associated data divided into segments
can be different length segments
segment number+offset
all program segments are loaded if no virtual memory
eliminates external segmentation suffers from internal segmentation
visible to user unlike paging
Segment table for each process that keep starting address of segment along with 
size of that segment because segments are of variable size so to check the valid address

TLB
virtual memory access requires at least two memory access one for PTE and one for actual data frame access
 with TLB,high speed cache for PTE, most recently used page table entries can be used to find the frame number If its not there then
1)access page table
2)
If page is in memory then update TLB and CPU genrates physical address
If page table is not in memory(checked with present bit in PTE) then its page fault and 
trap to OS save the state of current process and transfer control to page fault handler
 i)read page from disk more process from running to blocked state
 ii)if no memory available then replace memory page to make space
 iii)update page table and more process from blocked to running

we cannot index TLB with page number because it holds only some of the page table entries so TLB holds both page number and PTE
In TLB  associative mapping is done that is all entries are checked simuiltaneoulsy


Page size
Small page size : less internal fragmentation,optimizes the use of main memory, more pages will be required per process hence larger page table, more pages means only part of page table can be in memory so number of page faults will double including the page table access from disk.
Large page size: disk device transfers efficiently

Virtual Memory
allows only part of process to be in memory
program size can be larger than all available memory
differences:Fetch policy,Demand Paging,Prepaging

Page replacement
Optimal page replacement policy clairvoyant or belady optimal
replace the page for which the time to next reference is longest
least page faults
impossible to implement, so used as benchmark
looks in the future  and finds out of present frames which will be used last or never

Least Recently used policy
replace page in memory that has not been referenced for longest time
decides on  principle of locality
looks in the past and find out of present frames which was used last
so a page reference string S with LRU and  page string reverse(S) with Optimal will give same result
difficult to implement
stack implementation Or counter implementation possible
stack algorithms does not suffers from belady anomaly like optimal and LRU
LRU does nearly as good as Optimal

solving LRU problems
mark the alphabet that are present in memory as they come
look to the left of new alphabet which alphabet in memory is to most left
replace that

First In First Out policy
without looking at the past or future it replaces pages in round robin order
a circular buffer
simplest easy to implement
in other words looks a the present page frames and replace the one that has been for longest time
suffers from belady anomaly that is increasing page frame increases page fault instead of decreasing.

How to solve FIFO page replacement problem
write the alphabet one below other until faults
when page fault cross the first alphabet and place new at last

Thrashing
more paging activity
solution is to use local replacement algorithm instead of global, process cannot steal frames from other process

//go through the counter based implementation and other algorithm that uses reference bits