% Template for a simple journal or conference style article

\documentstyle{article}
\begin{document}

\title{\bf CIS 629: Project No.3\\ \ \\ RISC Q and A}
\author{Sameer S. Shende}

\maketitle

\begin{description}
\begin{enumerate}
\item 
To describe Microprogramming, we have to look at the organisation of the CPU.  
A processor consists of hardware registers, ALU ,three types of data busses 
(A,B and C) for operands to be fetched and written back into the registers.
To execute an instruction, data needs to be put out on the appropriate
data busses, it needs to be latched, the ALU needs to get the operands and
the instructions, and executed, and again a significant amount of control
signals need to be generated to synchronise the operations of the various units
in the CPU. A Microinstruction consists of a series of bits (22 bits as described for a specific machine in the Tanenbaum text). A microinstruction thus controls the data path and the control path in a CPU affecting the Memory address register, memory buffer register, ALU operation, initiating a read or a write request
,selecting busses for data transfer between units etc. 

A microprogram consists of microinstructions and defines the instruction set.
A microprogram is stored in a writable control store (area within the  CPU for
storing the equivalent of a big instruction set). A particular instruction can 
be implemented in the microprogram by using an interpreter for the microinstruction. The advantage of coding part of the software in microprogram was that 
new efficient (read complex) instructions could be tailor made for a specific
software requirement and implemented for the processor as a set of instructions
which resided in a control section of the processor (ROM or RAM). This storage
area which controlled the operation of the processor (by means of the microinstructions it contained) was known as the "writable control store". So, a language 
similar to the assembly language was developed in which the microprogram was
coded and interpreted to form micro-instructions which controlled the overall
CPU operation. This is described as microprogramming. 
\item
A large number of instructions in the ALU are 3 operand instructions. These are
Add, Subtract, Multiply, Divide on integers, floating point numbers etc. Typically, if we consider the add instruction A= B + C it needs two memory addresses
to be generated to fetch the operands B and C (and load these in registers),
then calculate the sum (ADD) and store the result in a register. This can be
stored in a memory location subsequently. In 3 - address instructions, the intermediate 
stage of fetching the operands and then executing it is not done. There can be
register-register (as described above), register-memory and memory - memory models of execution of instructions. In a memory - memory instruction, the 
address of the memory location where the address of the operand is located is specified and the address where the result has to be stored using the same indirection is specified.
The three address instruction format which requires data to be fetched or 
written to memory three times in order to execute the instruction has the
advantage that its very easy to implement and the compilers are easy to write
for such a model. The obvious disadvantage for such a scheme is that it is 
inefficient. Consider the case when an address is generated from the CPU - this being the virtual address, it has an overhead of translation into the physical address, searching for it in a cache memory and if there's a cache miss fetching
it from the main memory during which time the processor waits (in the absence
of instruction pipelining).  

A RISC architecture uses instruction pipelines to concurrently fetch data 
and instruction required for a later instruction, and execute the current 
instruction.  It also relies very heavily on the fact that it can reuse the
data in the registers rather than getting it from memory. The data is not 
flushed out of the registers after an instruction is executed but retained 
for future use. RISC uses explicit LOAD and STORE instructions to get data.
This way the 3 addresses need not be generated for every 
instruction. It relies on the compiler to optimally use the data in the registers. RISC tries to execute every instruction in just one clock cycle (at the minimum). 

\item
A delayed branch is used in RISC machines to minimise the bubbles appearing
in a pipeline. The stages in the execution of an instruction is IF (instruction
fetch which gets the instruction using the program counter), ID (instruction
decode to find what the instruction should do), OF (operand fetch - which gets the operands needed for the instruction), OE (operand execution - the actual
execution of the instruction) and OS (operand store - which stores the results).
Since each memory reference takes a cycle multiple of these stages are
pipelined where the operand execution stage can execute concurrently with the
operand fetch stage of the next instruction). So, it is critical that the 
pipeline is always full and all units are executing to give the maximum throughput.

However, when a branch instruction is encountered, the address of the next
instruction cannot be determined till the actual execution of the branch which
can cause a buuble to appear in the pipeline. A delayed branch executes the
instruction following the branch instruction when the instruction fetch of the 
next instruction is in progress. So, the effect of the branch is delayed by 
one or more cycles. Thus, the pipeline is kept full and the bubble is not introduced in the instruction pipeline. This poses a difficulty to a the compiler 
writer who has to implement the delayed branch in the compiler so that the 
results of the execution of the instruction following the branch can be used.
For e.g.,
Consider the execution of the following instructions
\begin{center}
\begin{tabular}{|l|l|l|}
\hline
{\bf Address} 	& {\bf Instructions}	& {\bf With Delayed Branch}\\
\hline \hline
1000		& INC C			& INC C\\
1001		& SUB B,A		& JUMP 1004\\
1002		& JUMP 1004		& SUB B,A\\
1003		& ADD A,C		& ADD A,C\\
1004		& INC A			& INC A\\
\hline
\end{tabular}
\end{center}

In this case, if the instructions were executed as shown in the first column, 
The jump instruction would have caused a bubble to appear. Instead if it is
relocated as shown in the second column and the effect of the Jump is visible
only after the SUB B,A has been done, then there's no bubble in the pipeline.
Thus, instead of executing SUB and then JUMP, the JUMP is initiated and the
operands for the 1004 are fetched at the same time as the execution of the 
SUB instruction. Thus, the optimised delayed branch can work just as well 
but introduce fewer bubbles in the pipeline. (It is important to note that in this case, the delayed brach worked because the destination of the branch or address did not depend on the executionof SUB instruction, if this was not the case, then the bubble would have appeared). 	

A delayed load is similar to the delayed branch instruction. A load or a store
operation requires that the address be computed in one cycle and the data be
fetched from the memory in the second cycle and used in the third cycle. During
the execution of one phase the other phase of the next load can be active. So,
in the case of a delayed load, the compiler puts another instruction in the 
pipeline while this is executing. From the paper by Patterson on RISC, they
claim that it can be done 90% of the times by the IBM and the Berkeley RISC
machine.

\item
RISC systems depend more heavily upon Compiler technology than the CISCs because
the advantage that can be achieved by using  the data from the registers, and 
filling the pipeline optimally has to be addressed by the compiler. The optimum
reuse of an item in a register (assuming a large number of registers) is done by the compiler. The compiler also checks if an operand generated by an instruction is required in the next cycle (independence of input-output) by the next
instruction and if that is the case, then it reschedules the instructions so
that there is no clash. This logic has to be built into the compiler in the case of RISC but is avoided in the CISC case. The compiler also takes care of keeping
the pipeline full by using branch prediction, delayed branch and keeping track
of branch history. By using virtual registers in the RISC architecture, if there's a conflict about using a register, then it can be sometimes resolved by using
different physical registers for the same logical register. This can be also done by the compiler (but is currently implemented in hardware). 
	
The compiler relies very heavily on registers and resolves all conflicts arising
out of using the same register by successive instructions in a manner which 
may result in inconsistencies or create a bubble in the pipeline.

Thus, RISC architects rely on efficient compilers to extract high throughput from the processor.

\item
Register windows are used by the RISC processor to ensure that arguments  in a procedure or a function call are not copied again and the register that stores an argument can be used in the next context after the program counter is changed following the execution of the function call.
If a certain set of registers is being used by a thread, and it calls a procedure, then the set of registers allocated to the called procedure could overlap with those of the calling procedure. This overlap is what can be termed as a 
"register window". Essentially, the underlying philosophy of the RISC architecture is to have as few loads and stores of operands as possible and to reuse these
in the registers. So, one way to maximise reuse is to implement some optimising
compilers to do this or to do it in hardware. While the possible opportunities
for this reuse can be easily seen in the compiler implementation, these would
be difficult to detect if we take the hardware approach. One area where a clear
cut reuse pattern can be seen is argument passing in the function call implementation. So, in the absence of compiler experts in the Berkeley project, they 
chose to implement the register windows.

\item
The clock cycles on some of the early RISC processors was longer than the corresponding clock cycle on CISC. For e.g., a T805 (from Inmos) came with a 20MHz 
clock while a i386 clock was 25Mhz, 33 MHz. However, the T805 had an onchip
co-processor (FPU) and a 4KB cache (reduced instruction gave more silicon space)
and so it did outperform the Intel 386 even with a i387. However, the RISC
clock frequency started increasing the CISC frequency and now it is definitely
more than the CISC processors. For e.g., a i486 and a Sparc processor had 
33 MHz and 50 MHz frequencies and Sparc II outperformed the i486. With the
clock doubler chips (the DX2, DX4 chips ) Intels 486 and Pentium perform at
rates of 66, 75, 100 MHz and correspondingly the DEC AXP Alpha processor
performs at 270 MHz (and will touch 400 MHz by next year). Also, PA-RISC 
7100 LC processor performs at 99 MHz. So, we can conclude that the RISC
processors today not only outperform CISC due to their pipeline design (e.g.,
MIPS R8000 @75MHz outperforms Pentium @100 MHz due to the floating point
pipeline) but are having higher frequencies of operation as well.

\item
The number of instructions in a RISC processor is very small and the instructions are simple. This gives a clear picture of the processor architecture to the
compiler and gives the barest minimum constructs for the compiler to use. It  
also means that complex operatoions need to be implemented in software by the
compiler but all the resources that the processor can offer in terms of the
pipeline, registers, on chip cache, floating point hardware unit are all in 
control of the compiler and it can efficiently use these.

\item
To see the MIPS R8000 there is a slight evidence of backsliding from RISC 
to the more complicated instruction set as seen in its Multiply and Add 
instruction (floating point a x + b) and because of the 5 stage pipeline that
it operates on we can see 4 floating point operations per clock cycle (in all
20 in 5 cycles) which accounts for 75Mhz * 4 = 300 MFlops. Also, a Linpack 
performance of 200Mflops (1000 x 1000) could be achieved only because of this
{\em complex} floating point instruction. In terms of compiler technology we 
see that in PowerChallenge series it not only does all the functions of a 
RISC compiler but there's a parallelising compiler as well which can create
concurrent threads of execution on IRIX 6.0 64 bit O.S. from a sequential code.
So, the trend seems to be to go for a more "hybrid" view of these technologies
(Pentium has a dual stage pipeline - a feature thet it probably picked up from
the RISC world, and in R8000 we see new exotic instructions which were the
forte of the CISC world) and to pick out the best features of both the worlds.



\end{enumerate}
\end{description}
\end{document}

% ------------ end of document ----------------------

% here are some templates of different environments you can cut and paste:

\begin{figure}
\vspace{3in}
\caption{}
\end{figure}

\begin{itemize}
\item
...
\end{itemize}

\begin{enumerate}
\item
...
\end{enumerate}

