慶應義塾大学
2016年度 春学期

コンピューター・アーキテクチャ
Computer Architecture

2016年度春学期
科目コード: 35010 / 2単位
カテゴリ:
開講場所:SFC
授業形態:講義
担当: Rodney Van Meter
E-mail: rdv@sfc.keio.ac.jp

第11回 7月14日
Lecture 11, July 11: Processors: Arithmetic

Outline of This Lecture

Structure of a CPU

ちょっと抽象的な絵ですが:

CPU block diagram
簡単に説明すると、CPUはこの機能の部品がある:

This week's lecture is about (some of) the things that go on inside the ALU, the real "heart" of what we often mean when we talk about "computation". However, in some respects, this topic is among the easier jobs that a CPU has, and it's easy to understand, so it's a good place to start.

Integer (整数型) Arithmetic

Let's look at some simple eight-bit, twos-complement (2の補数) binary numbers:

0 | 00000000
1 | 00000001
2 | 00000010
3 | 00000011
4 | 00000100
8 | 00001000
16 | 00010000
32 | 00100000
64 | 01000000
65 | 01000001
127 | 01111111
-1 | 11111111
-2 | 11111110
-3 | 11111101
-128 | 10000000
The leftmost bit is called the sign bit. To negate a number, flip every bit, and add one. This representation of signed numbers is called twos complement. Twos complement has a couple of advantages: a) the addition circuit for signed and unsigned numbers is exactly the same, and b) there is no redundant representation of zero, as in ones complement or sign-magnitude representation.

Integers can also be represented using a biased representation, which allows negative numbers to be written. Although the bias can be any number, in practice it is generally a power of two (or a power of two minus one). Here are some eight-bit numbers with a bias of -127:

-127 | 00000000
-126 | 00000001
-125 | 00000010
-124 | 00000011
-123 | 00000100
-119 | 00001000
-111 | 00010000
-95 | 00100000
-63 | 01000000
-62 | 01000001
0 | 01111111
1 | 10000000
2 | 10000001
3 | 10000010
128 | 11111111
We will see biased numbers again when we discuss floating point, below.

Addition

Let's look at an addition:

19 | 00010011
+ 14 | 00001110
=33 | 00100001
Notice how the carry moves up the word, the same as in decimal arithmetic. The simplest form of adder is known as a ripple carry adder. Arithmetic circuits are usually formed from two simple types of blocks: the half adder and the full adder. The half adder takes in two inputs and generates two outputs: the modulo two sum of the input bits, and the carry.

Half-adder circuit from Wikipedia
Half-Adder Logic Table
InputOutput
ABCS
0000
0101
1001
1110
And the full adder:

Full-adder logic circuit from Wikipedia
Full-Adder Logic Table
InputOutput
ABCinCoutS
00000
01001
10001
11010
00101
01110
10110
11111
From these two types of blocks, we can easily construct a ripple carry adder, by connecting the carry out of one full adder to the carry in of the next. The circuit is very simple. The problem is that it is slow: O(n) gate times are required to add two n-bit numbers.

4-bit ripple carry adder

There are a number of other types of adders:

And still others; we will not go into them in detail here.

Multiplication

The most obvious way to do multiplication is simply to repeatedly shift and add. This approach also happens to be the slowest way to multiply. CPUs generally contain a specialized circuit for multiplication, known as a carry-save multiplier, which operates by overlapping the propagation of carrys with the next stage of the addition. Using a carry-save multiplier, the latency of a multiplication is roughly twice that of an addition.

Floating Point Arithmetic

Representation

A floating point number (浮動小数点) consists of three parts:

We will assume that the base is two. The significand is the fraction; because floating-point numbers are stored in a normalized representation, the high-order bit of the fraction is always one, and we do not have to include it in the register. In IEEE 32-bit floating-point numbers, the exponent is 8 bits, with a bias of 127.

e as a floating point number,
			 01000000001011011111100001010100 e as a floating point number,
			 01000000001011011111100001010100
In this example, the sign bit is zero, so the number is positive. The significand is represented as 01011011111100001010100, but that doesn't include the assumed leading one, known as the hidden bit. With the decimal point and the hidden bit, our number is 1.01011011111100001010100. The exponent is 10000000, which, with bias, represents "1". So, we need to move the decimal point one digit to the right: 10.1011011111100001010100. This number now represents

21 + 2-1 + 2-3 + 2-4...
= 2 + 0.5 + 0.125 + 0.0625...
= 2.71828175

Advantages and Disadvantages

Operating on Floating-Point Numbers

Addition of floating-point numbers requires that both numbers have the same exponent; usually, the larger one is left normalized and the smaller one is aligned to match. Then standard integer addition can be performed, after which the result must be renormalized (have its exponent adjusted so that the high-order bit is one). The steps are as follows:

  1. Subtract exponents
  2. Align significands
  3. Add (or subtract) significands, produce sign of result
  4. Normalize result
  5. Round
  6. Determine exception flags and special values
Multiplication of floating-point numbers does not require the initial alignment step.

  1. Initial multiplication
    1. Multiply magnitudes (result is 2m bits, for two m-bit significands)
    2. Add exponents
    3. Generate sign
  2. Normalization
  3. Rounding

Exceptions

So far, we have ignored errors, but there are several important cases that must be tracked in arithmetic:

In different processors, those exceptions behave differently. In all processors, a flag will be set; in processors, an exception is thrown. Some processors always throw an exception, others do it under program control, either with a processor control flag that is set by the programmer, or by using different instructions that do or do not throw exceptions.

Final Thoughts

宿題
Homework

  1. Draw the graphic symbols and write the truth tables for: I expect these to be your own drawings, not taken from the web!
    1. AND gate
    2. OR gate
    3. XOR gate
    4. NOT gate
    5. NAND gate
    6. NOR gate
  2. What decimal values do the following 32-bit twos-complement integer numbers represent?
    1. 00000000000000000000000000001111
    2. 00000000000000000000000000010000
    3. 00000000000000000000000000100000
    4. 11111111111111111111111111111111
    5. 11111111111111111111111111110000
  3. Tell me what decimal values the following floating point numbers represent:
    (First, identify the sign bit, exponent, and significand, then work from there. Also, two of the numbers are only slightly different, but I want to know what that difference is!)
    1. 00000000000000000000000000000000
    2. 00111111100000000000000000000000
    3. 10111111100000000000000000000000
    4. 00111111000000000000000000000000
    5. 01000000000000000000000000000000
    6. 01000000010000000000000000000000
    7. 01000000010000000000000000000001
    8. 01000000010010010000111111011010
  4. Write a program (in C or your choice of language) that determines the smallest floating point number your system can handle. Start with x = 1.0 and divide by 2 repeatedly until x = 0.0. Print the results as you go along. Print both the values and the number of iterations of your loop. Also, include your source code! As always, you should document the environment you are running in.
    Include the output of both of those programs! Advice: you will need to print out the numbers with a higher number of digits of precision than the default.
    1. Tell me what environment you are working in. Machine type, OS, compiler.
    2. Do for type "float".
    3. Do for type "double".
  5. Do the same thing for the largest number.
    1. Do for type "float".
    2. Do for type "double".

Next Lecture

Next lecture:

第12回 12月24日
Lecture 12, December 24: 入出力
Basics of I/O and Storage Systems

Readings for next time:

Additional Information

その他