Comp 150-001, TTh, 11:00-2:00, DH-339

Class 1

Intro, ground rules. One in-class exam and one final.
The last hour of each class will be devoted to a lab; the first several labs will be on the Python language.

Topics:

Computers are good for:

History of Computers

Early arithmetic: abacus, logarithms, slide rules (~1600), mechanical calculators (later)

Jacquard loom, 1801: the first mechanical device controlled by a "program" (stored on cards).
Ned Lud and the Luddites, 1811: oops

Charles Babbage (1791-1871) and the mechanical Analytical Engine. Babbage began work on the Analytical Engine in 1822 and continued for the rest of his life. It was to be a gear-driven computer; early versions were application-specific. Alas, mechanical gears  have enough "slack" that Babbage's plans were difficult to implement.

Lady Ada Lovelace was Babbage's chief programmer (and in some sense the world's first programmer) The two of them realized that the machine could do much more than simple arithmetic and control. Ada in particular understood they were working on a general-purpose computer that could, with enough resources, compute anything, and that computation could be symbolic rather than purely numerical. Ada even proposed that the machine might compose music.

Both Ada and Babbage led somewhat tragic lives.

Ada's name might be given in full as Ada Augusta Byron King, countess of Lovelace There is not complete agreement on how in modern times to refer to her, but "Ada" is common even if it is not exactly parallel to "Babbage".

Hollerith cards & 1890 census: Hollerith's Tabulating Machine Company produced machines that assisted with simple recordkeeping, sorting, and tabulating. Through a sequence of mergers, this company became IBM.

1936: Alan Turing developed the conceptual computer later known as a Turing machine. This was completely abstract; they were entirely impractical (and not intended to be practical). This did establish the core features needed for computing, though: conditional instructions and lots of memory.

Analog computers: electronic circuits that, when you provided a set of inputs (eg as voltages) would generate an output voltage that represented the value you were looking for. (There were also many paper analog computers, or "nomographs": you found your inputs on the axes, and found your result at an appropriate intersection point.

John Atanasoff in 1939 began using electrical signals to build digital computers to solve specific problems (eg linear equations with 29 unknowns). He did not build a general-purpose stored-program computer.

About the same time, Konrad Zuse was building a similar machine, but using relays instead of tubes. This resulted in failure. However, Zuse had the brilliant idea of having the program be stored within the computer itself, so the machine was not limited to those tasks for which it was hardwired. Ada may also have understood this principle. This changes the computer from "hardware designed to solve problem X" to "hardware designed to solve any problem, provided you can supply a program".

Neither group (Atanasoff or Zuse) really completed their work. (Atanasoff's computer did do some computations, but it proved inflexible. However, the importance of an electronic machine to perform complex calculations should not be underestimated.)

Aiken, at Harvard, built a working electromechanical machine a few years later, the Mark I. This was the first real working general-purpose computer; it became operational in mid-1944.

1943: Turing & others at Bletchley Park, England, built Colossus: an all-electronic machine for decrypting German messages. It did not, however, do basic arithmetic.

Mauchly & Eckert's group built the all-electronic ENIAC (Electronic Numerical Integrator And Computer); it became operational in 1945.  However, ENIAC was programmed by configuring a complex array of patch cords and switches.

Understanding this limitation, Mauchly & Eckert moved on to the EDVAC, which incorporated an idea generally attributed to John von Neumann (who was part of their group): the idea of storing the program in memory, in the same memory space as was used for data (not, of course, overlapping). The computer would fetch and "execute" each instruction stored in memory in turn. This meant adding to the CPU an entire mechanism for fetching, decoding, and interpreting instructions, but subsequent history has made it clear that this was the Right Idea. This strategy is often called the von Neumann computer.

EDVAC eventually worked, but a group in Manchester, England started later and got their stored-program computer working first.

Somewhere around then the CEO of IBM, Thomas J Watson, is alleged to have said that worldwide there would be a demand for at most five "computers":
    "I think there is a world market for may be five computers." – Thomas Watson, chairman of IBM, 1943.
But at the time, a "computer" was a person who did arithmetic for a living! So the story is probably apocryphal.

Transistors were invented in 1947, appeared in "real" computers in 1957. At that time transistors were discrete components. Transistor radios typically had five of them.

From ~1948 to 1959, computers slowly evolved into general programmable machines routinely used by businesses and scientific/engineering groups.

1948: magnetic drum, precursor to disk
1948: An Wang invents "core" memory; marketed in 1951
1949: magnetic tape

1951: Rand introduces the UNIVAC, the first 'mass-produced' computer.
1952: IBM introduces Model 701, their first electronic computer (later the 704, and 7000 series)
1956: disk memory, the size of a refrigerator. Later the size will be reduced to that of a washing machine. ;-)
1957: IBM releases the first Fortran compiler

Dale & Lewis call 1951-1959 the era of First-Generation Software. Programming was done in machine code. Eventually, assemblers were introduced that could generate machine code from more-or-less human-readable assembly code, a textual representation of the binary machine code. There was a one-to-one correspondence between lines of assembly code and individual machine instructions.

1959: Available computer languages include Fortran, Cobol, Algol, Lisp. However, lots of programming was still done in assembly code. 

The early Fortran compilers did an amazing job at generating machine code almost as fast, or sometimes faster, as hand-crafted assembler code. Programmers were constantly concerned that high-level languages were not fast enough.

1959-1965 was the era of Dale & Lewis's Second-Generation Software.

1965: IBM/360, and OS/360
    The 8-bit byte is born
In some sense the 32-bit IBM/360 was one of the first "modern" systems, though it has steadily evolved. The IBM/370 was introduced, for example, in 1970, and the system evolved into the IBM/390 in 1990. Other competitors in existence in 1965 have largely disappeared. Standard System/370 features included support for multiple processes and tasks, and virtual memory. Descendants were still in widespread use in 2000, when IBM introduced the 64-bit 'zSeries architecture' that gradually replaced the 32-bit versions. The 'z' is meant to stand for zero downtime, ie 100% reliability (achieved through redundancy).

The IBM/360 essentially ushered in the era that Dale and Lewis identify as Third-Generation Software. Tools included loaders to load programs into memory, and linkers to combine programs with libraries. A central third-generation feature was that programs now almost always ran under the direction of an operating system, even though early OS's were relatively primitive.

The main way of working with an IBM/360 was through batch mode: one submitted ones job, and later (the delay varied from a few minutes to overnight) received the printout. Early job submission was through punch cards. This was known as "batch processing".

A contemporary of IBM in the 1960's was Digital Equipment Corporation, or DEC. They produced minicomputers intended for scientific/engineering/industrial use, beginning in 1963 with the PDP-5 and then the PDP-8 in 1964. These were odd-sized-byte machines; the PDP-11 in 1968 was DEC's first 8-bit-byte machine. PDP-11's were very popular. Originally the size of a four-drawer file cabinet, they eventually shrank to PC-size but the 16-bit address space made them obsolete by ~1985.

1965 also saw the beginning of work on MULTICS, an early time-sharing OS. It was apparently never terribly popular, though it did work. It is best known for giving rise to UNIX (as a deliberte attempt to find an alternative to MULTICS).

1971: first integrated-circuit (single chip) microprocessor. gave rise to computers, calculators, and all sorts of other devices.

Early batch systems handled one process at a time. In order to maximize utilization of the expensive CPU, relatively early systems were capable of storing multiple programs in memory at a time and multitasking: when one program was waiting for data from the disk, it would be suspended, and another program would run. This was considered to be non-preemptive: your program only gave up the CPU "voluntarily".

Towards the end of this era, "interactive time-sharing" became more prevalent. This involved preemptive multitasking: a timer would interrupt the CPU every 10-100 milliseconds and the CPU would (under the direction of a part of the OS called the scheduler) suspend the process that had been running and resume another one. This allowed the CPU to appear to be executing several processes simultaneously. At first this was done so that several batch jobs could be worked on simultaneously, but then evolved into time-sharing where several users worked continuously at terminals, running programs by issuing commands. This feature was extremely popular with early computing researchers. IBM had TSO for this ("Time Sharing Option"); MULTICS and UNIX incorporated this from the beginning.

Time-sharing goes back to 1957; John McCarthy's group implemented it on an IBM 704 that year based on a paper by Bob Bemer. The final version, CTSS, the (in)Compatible Time Sharing System, was released in 1961. The Dartmouth Time Sharing System was released in 1964; it was very influential.

The first Unix system was begun at Bell Labs in 1969 by Dennis Ritchie and Ken Thompson, who were dissatisfied with the MULTICS approach. An important feature of UNIX was that it was the first OS to largely be written in a high-level language (called C); prior OSs were written almost entirely in assembler. The Unix date/time of 0 represents the last second of December 1969.

Linux is a unix-like kernel with the GNU open-source tools.

Dale & Lewis fourth generation: 1971-1989. During this period, "structured" programming in high-level languages became ubiquitous. The standard office applications (word processors, spreadsheets, databases) emerged. Bitmapped graphical displays emerged.

1976: Apple computer
1981: IBM PC
1984: Apple macintosh

Bitmapped Displays

Apple is known for bringing the bitmapped display to the masses with the 1984 macintosh, although there were earlier DOS-based programs that could display graphics. (There was also the 1983 release of the Apple Lisa.) The X windows project (windows for unix/linux) also began in 1984, vaguely descending from the Blit terminal (1982).  The Blit terminal could support multiple windows, selectable by mouse, but each window was limited to a command-line shell program. (The letter X of X windows was chosen as a successor to the W project, presumably named for Window.) Apple took the idea from graphical displays implemented at Xerox PARC (Palo Alto Research Center). Xerox had developed the Alto in 1973, and the Star in 1981; both implemented essentially all of the basic macintosh features.

Microsoft copied the macintosh implementation wholesale when creating Windows. A lawsuit determined that they in fact had a valid license. Microsoft contributed very little by way of innovation (though they did start adding their own features beginning with windows 95).

The core idea of bitmapped displays is that a portion of the main RAM is "mapped" to the video system. Each bit (or byte, if color is used) corresponds to one pixel. Usually libraries are used to do all the writing to video memory; on contemporary systems the video memory is "protected" and so system interfaces must be used.

History of the electronic calculator

The first one was developed ~1963.TI marketed one beginning 1967; not too successfully. Early calculators had circuit boards and several Integrated Circuits (ICs).

1971: Ted Hoff at Intel designed a single-chip calculator chip for Busicom. Hoff had two choices:

  1. Create a calculator-specific chip
  2. Create a general computer chip, that can run a stored calculator program.
The Intel 4004 was born. Later 8008, then 8080, then 8088 (original IBM PC chip), then 8036, then 80286, then 80386 and on to the Pentium. The so-called "386" architecture is still current, only now beginning to be replaced by 64-bit machines. The "8" in the early model numbers refers to the 8-bit "bus" Note that calculators need very little memory: just a display, an accumulator, and maybe another register or two for square roots.

Let's follow up on this:

Typical CPU: executes a sequence of instructions stored in memory. Execution is in sequence, unless JUMP instruction is encountered. Some instructions have an ARGUMENT: this can be a memory reference or a number. Early computers had a single register or accumulator that held the current value; all operations were done to this accumulator value (computers shortly added more than one register, but then bits in the instruction had to be allocated to specifying which register).

In chapter 7 of Dale & Lewis, the Pep/7 virtual machine is presented. There is a single accumulator; all operations are performed with respect to this. Some simplified examples:
    LOAD addr    // load the contents of memory location "addr" into the accumulator
    STOR addr    // store the contents of the accumulator at the specified location
    ADD addr       // add the quantity at the specified address to the accumulator
    ADD #5          // Add the value '5' to the accumulator
    CLEAR         // sometimes AND #0, sometimes LOAD #0
    TEST             // not actually used in Pep/7
    BR addr    
    BREQ addr               // branch to the specified addr if the accumulator is zero

Actually, Pep/7 uses LOADA, STORA, ADDA, and uses a second operand of 'i' or 'd' (immediate or direct) to specify in a LOAD or ADD whether we're treating the following number as an address or the literal quantity.

Address Space

Generally speaking, an 8-bit machine has an 8-bit bus (formerly buss); that is, 8 bits at a time can be transferred to and from memory and peripherals. Similarly 16-bit and 32-bit.

The more immediate bit-sizing concern, however, is addressable memory. Each byte in RAM is numbered, starting at 0. A memory address generally has to fit into one "word" (approximating the bus size). A 16-bit address space maxes out at 216 = 64KB of memory (the first 16-bit-address machines had less than that). This puts a pretty hard ceiling on how much data a program can store in memory, or even how big the program itself can be. The IBM/370 had 24-bit-addressing, for a maximum memory size of 224 = 16 megabytes. The world then moved rapidly to 32-bit addressing, which can address 4 GB.

Most servers purchased today are 64-bit-address systems, though that wasn't true five years ago. Generally database systems are the first adopters, as they like to keep essentially the entire database in RAM.

The original IBM PC had effectively 20 bits of address space, or 1 megabyte. However, most machines were originally shipped with about 16 KB, and MS-DOS memory-mapped the BIOS in at address 640KB. This was originally seen as "we'll never get there", but towards the end of the PC era everyone was struggling with ways to work around the "640KB limit". Bill Gates is supposed to have said, "640KB should be enough for anybody", but I'm not aware of concrete evidence.

Internal Representation

How are we going to store things in a computer?

There is some debate as to whether 0=off, 1=on or vice-versa, but irrelevant

binary integers: 23 v 10111 v 00010111

Dividing into units: related to management of "memory"
    bytes
    words

Memory (RAM)
    binary integers
    floating-point and negative integers

Memory (disk)
    not directly ADDRESSABLE
    divided into sectors, clusters (physical v logical sectors)

ASCII



Python

The language was named for Monty Python.

Start Idle (named for Eric Idle, one of the Monty Pythoners).

The first thing to notice is that python is completely interactive. You type expressions and definitions; it evaluates them and prints the result. It is possible to do real I/O with python, but we won't need it for a while.

a=600
b=400
a/b
??