.NONUMBER .LM 0 ^PY^- .PAGE SIZE 58,85 .LM 10 .RM 75 .NO FILL .NO JUSTIFY # .SKIP 5 .CENTER The RSX Multi-Tasker .CENTER September, 1986 .SKIP .CENTER ^IS144^G"All the News that Fits, We Print"^IS204^G .SKIP .CENTER Fine Realtime Commentary Since 1975 .SKIP 6 .CENTER ^&Table of Contents\& .SKIP 2 .TAB STOPS 60 The Editor's Corner RSX-1 The "New DECUS" and the "Old Guard" RSX-1 Submitting Articles to the Multi-Tasker RSX-2 Answer to Last Month's Quiz RSX-2 And That's The Way Things Are RSX-2 The Bag of Tricks: MACRO-11 RSX-2 Improving M-Plus Spooler Performance RSX-4 System Tuning Under RSX-11M-Plus RSX-7 The Inside Scoop on BRU RSX-13 .JUSTIFY .FILL .PAGE .COMMENT .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT The Editor's Corner .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT # .SKIP 5 .AUTOPARAGRAPH .CENTER ^&The Editor's Corner\& .SKIP .CENTER Bruce R. Mitchell .SKIP 2 This is a particularly interesting issue for readers interested in improving the performance of your systems. There are two articles dealing with the topic; one by Kreigh Tomaszewski on general system tuning, and one by the editor on improving performance of the M-Plus print symbionts. There's also a very interesting article in the Bag of Tricks which I have already found useful. Without further ado, here's this month's editorial broadside. .TEST PAGE 5 .SKIP 2 .CENTER ----- The "New DECUS" and the "Old Guard" ----- There has been much ^IS144^Gsub rosa^IS204^G discussion within the Society over the last year on the so-called "New DECUS" as opposed to the "Old Guard". Much smoke has been generated. The Editor perceives two main viewpoints among the discussors, and presents them here for consideration by readers who may not be ^IS144^Gau courant^IS204^G with such matters. The "New DECUS" viewpoint: DECUS and Digital have come a long way since the formation of the Society. The days of the single-user, isolated system and the technically oriented user are almost ended. Today's machines are large, multi-user, and networked; the users of those machines are, in general, technically unsophisticated. DECUS should change its orientation to reflect this change in the Digital user base. The "Old Guard" viewpoint: DECUS was established as a user society for end users - viz., programmers - and promotion of technical excellence in those users. The majority of those users are not particularly interested in the latest office automation products from Digital; they are interested in accomplishing a job of work. DECUS should retain and promote its orientation toward technical excellence among the users of Digital machines. This is a matter which affects all of us as members of the Society. The Editor withholds his personal opinion, having no wish to gore anybody's ox in print. He does, however, welcome ^IS144^Gconstructive^IS204^G comments from readers on this topic. (The Editor welcomes comments from readers on almost ^IS144^Gany^IS204^G topic!) .TEST PAGE 5 .SKIP 2 .CENTER ----- Submitting Articles to the Multi-Tasker ----- Please, oh pretty please, submit machine readable media if you can. RX01/RX02 floppy or 800/1600 BPI 9 channel magtape are best. Any format is acceptable except ROLLIN, PRESRV or VMS backup. BRU and DOS FLX formats are well-liked by the Editor's tape drive. Submissions which aren't machine readable take longer to get into print. The editor is lazy and types mass quantities only once a month when progress reports are due. If you preformat a submission in RUNOFF format, please set left margin 10, right margin 75, and when changing margins use incremental changes rather than absolute. The editor will bless you for the consideration. Send all submissions to: .SKIP .NO FILL .NO JUSTIFY Bruce R. Mitchell Machine Intelligence and Industrial Magic PO Box 816 Byron, MN 55920 .JUSTIFY .FILL .TEST PAGE 5 .SKIP 2 .CENTER ----- Answer to Last Month's Quiz ----- The first letter of every paragraph in the Editor's Corner. .TEST PAGE 5 .SKIP 2 .CENTER ----- And That's The Way Things Are ----- _... this month in Pool Lowbegone, where all the programmers smell strong, all the secretaries are good-looking, and all the task runtimes are above average. .COMMENT .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT The Bag of Tricks .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT .TEST PAGE 15 .SKIP 6 .CENTER ^&The Bag of Tricks: MACRO-11\& .SKIP .CENTER Jim Bostwick .CENTER Cargill, Inc. .CENTER Minneapolis, MN .SKIP This month's article is on round-robin scheduling in user tasks. When a user task is serving more than one physical device simultaneously, a common approach is to assign each device a logical unit number (LUN), assign an unique event flag to each LUN (usually equal to the LUN), queue a read-without-wait to each device, and wait for the logical OR (WTLO$) of all the event flags. When the WTLO$ completes, at least one unit has completed I/O; each event flag is then checked to see who completed. There are a couple of large holes in this approach. One is that if a large number of devices are served, it's easy to run out of event flags. Another is that if more than 16 event flags are required, a single WTLO$ doesn't do the trick. A final objection is that if searching always starts at unit 0, and there are 256 units, unit 255 may never be serviced by the task. This is a better approach. Only one event flag is required, and every unit gets equal service. Read-without-waits are hung on every LUN, all of which set the event flag IOFLAG. When any I/O completes, a round-robin search algorithm is used to equalize service priorities - the unit just serviced gets lowest priority while everybody else gets a shot at the CPU. Presumably, this type of code is used to serve many identical devices, so a single QIO DPB suffices. All that is necessary is to remember that when a read QIO is hung on a logical device, the DPB for that device must be modified to change the LUN (Q.IOLU) and the I/O status block (Q.IOSB) parameters. It is essential that read-WITHOUT-wait QIOs be used if this code is to work. All I/O status blocks are kept in a contiguous block of words at IOSTAT. Note that the unit activity determination uses an RSX feature; the I/O status block is zero when a QIO is pending, and nonzero when it completes. The value of ROBIN - the round-robin search variable - is unimportant when the task is initialized. It is self-correcting if garbage is left in it. .SKIP 3 .NO FILL .NO JUSTIFY WAITIO: WTSE$ IOFLAG ; Wait for I/O to complete IOSTAT: .BLKW ; I/O status block array # # ... code to hang read QIOs on every served device ... # ; Top of recurrent program execution. We get all I/O ; through this I/O scanning routine. All units get equal ; access to the program due to round robin scheduling. # 10$: INC ROBIN ; Increment RR to next unit CMP ROBIN, _#MAXUNT ; Trying to look at illegal unit? BLOS 20$ ; If not, bypass the resetting # MOV _#1, ROBIN ; Reset to look at unit 1 again # 20$: MOV ROBIN, R0 ; Load base of search into R0 # 30$: MOV R0, R1 ; Copy searched unit number to R1 DEC R1 ; Change LUN to 0-base for lookup ASL R1 ; Multiply it by 4, because I/O ASL R1 ; status blocks are 4 bytes TST IOSTAT(R1) ; Is I/O complete for this unit? BNE 50$ ; If so, go process it # INC R0 ; Set up to look at the next unit CMP R0, _#MAXUNT ; Trying to look at illegal unit? BLOS 40$ ; If not, bypass the resetting # MOV _#1, R0 ; Reset to look at unit 1 again # 40$: CMP R0, ROBIN ; Have all units been searched? BNE 30$ ; If not, go search the next one # ; Nobody's active, so sleep and wait for an I/O to complete # DIR$ _#WAITIO ; Wait for any I/O to complete BR 20$ ; And go process it when it does # # ; Round-robin scan completed. is active. Process it. # 50$: ... I/O completion processing code ... ... replace I/O on unit just processed as last thing ... BR 10$ ; Go back, check for I/O again .JUSTIFY .FILL .COMMENT .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT Improving M-Plus Spooler Performance .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT .TEST PAGE 12 .SKIP 6 .CENTER ^&Improving M-Plus Spooler Performance\& .SKIP .CENTER Bruce R. Mitchell .CENTER Machine Intelligence and Industrial Magic .CENTER PO Box 816 .CENTER Byron, MN####55920 .SKIP A local site recently purchased several "Brand Q" laser printers to replace their electrostatic printer/plotters. Their initial intention was to attach the printers from the task generating the plots, rather than spool the laser printers. However, after some discussion of the relative merits of each method, it was decided to try spooling the printers. Some difficulties were encountered in the spooling subsystem. Most of them were readily overcome, and the printers had been running for some time before it was noticed that there was a great deal of random seeking occurring on the disk containing the plot files. It was discovered that when the print symbionts (the "spoolers") were stopped, much of the seeking disappeared. Further investigation into the problem revealed two surprises; first, that the print symbionts are too heavily overlaid, and second, that the print symbionts do not do big-buffered or multibuffered reads. These were interesting discoveries, to say the least. The overlaying issue was addressed first, with gratifying results. The print symbionts are PR:5 tasks. Even so, there are still 3 APRs available to the task. It was found that LPPFSL.TSK, as built, occupies only 3072 of the available 12288 words. But, with over 9000 words available, the taskbuilder map shows that the task is partitioned into 10 overlays, overlaid 2 levels deep, and some of the overlays are only 500 words in size. This is inefficient at best under M-Plus, where FSL tasks and large memory are the norm. With little effort, the overlay descriptor for the task was modified as follows: .SKIP .NO FILL .NO JUSTIFY .NAME LPP .ROOT LPP-[1,24]LPP/LB:RECEIV:POTS:IOPRT-E-Q-*(A,B,C,D) E: .FCTR SY:[1,54]RSX11M.STB Q: .FCTR [1,24]QMG/LB:QMGSYM A: .FCTR [1,24]LPP/LB:INIT:JOBSTR:JOBEND B: .FCTR [1,24]LPP/LB:FILPRO:CONT:ERPRT:PRT-B1 B1: .FCTR [1,24]QMG/LB:FPRIV:PRCO C: .FCTR [1,24]LPP/LB:FLPAG:FLINI:JBINI:FLGEN D: .FCTR [1,24]LPP/LB:PRTDN:DONE .END .JUSTIFY .FILL This new overlay structure reduced the overlay level from 2 to 1, reduced the number of overlays from 10 to 4, reduced the size of the task image from 38 to 27 blocks, and reduced the number of overlay reads from the system device as a side benefit; this was very useful as many files were being spooled. The in-memory size of the task increased 480 words, from 3072 to 3552 words. It was felt this was a very small price for the return on those 480 words. It was theoretically possible to flatten the symbiont completely, but when this was attempted, the Taskbuilder didn't like it. The GBLDEFs in the taskbuild command file started to fail. Though the spoolers were running faster, they were still generating unacceptable traffic on the spool disk. The tasks generating plot files were generating quite enough random traffic on the spool disk without the spoolers making it even worse. The possibility of big-buffering in the symbionts was considered. It was found that big-buffering in the symbionts was indeed feasible. Three one-line changes were necessary in symbiont source code. In the distribution kit source file [121,10]RECEIV.MAC, the line: .SKIP ########FSRSZ$##1,512.,BUFFER .SKIP which defines an FSR1 block storage area of 1 block in size, 512 bytes, in PSECT BUFFER, was changed to: .SKIP ########FSRSZ$##24.,, BUFFER .SKIP which defines an FSR1 block storage area sufficient for 24 disk blocks. In the distribution kit source file [121,10]FILPRO.MAC, the line: .SKIP ########.MCALL##OFID$R,DIR$ .SKIP which calls the file open and directive macros, was changed to: .SKIP ########.MCALL##OFID$R, DIR$, FDBF$R .SKIP so that the runtime FDBF$ (define file buffer area parameters) macro was available. Insertion of the first line in the sequence below was also necessary to restore the buffer size before each file open, as this word is destroyed by FCS after the file is opened: .SKIP ########FDBF$R##R0,, _#<24.*512.>########; Read 24 blocks per I/O .BREAK ########OFID$R##R0#######################; OPEN THE THING .SKIP This increased the task size to the close order of 10K words and caused a marked improvement in disk traffic. Before this change, the spoolers "fought" with the application tasks for disk I/O, with consequent degradation of I/O bandwidth on the spool disk. After the change, I/O bandwidth increased greatly. A pleasant side effect of these changes was that it was possible and actually necessary to lower the spooler priority to 51 from the normal 70. At priority 70, the new versions of the spoolers became so much faster that they ate up all the time the system made available. One final warning: The information in this article was gathered on, and is correct for, RSX-11M-Plus V2.1 Update E. V3.0 may have changed the files to which reference is made. .COMMENT .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT System Tuning Under RSX-11M-Plus .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT .TEST PAGE 12 .SKIP 6 .CENTER ^&System Tuning Under RSX-11M-Plus\& .SKIP .CENTER Kreigh Tomaszewski .CENTER Amway Corporation .CENTER 7575 E. Fulton Road .CENTER Ada, MI####49355 .SKIP 2 .LM +10 .RM -10 ^IS144^GThe graphs which accompanied this article, regretfully, did not reproduce well enough for inclusion. My apologies to the author. --- The Editor^IS204^G .LM -10 .RM +10 .SKIP System tuning under RSX-11M-Plus can mean many things. At Amway Corporation, it means minimizing terminal response time while maximizing throughput of the machine. Before going into how we meet these often conflicting goals, let me tell you a little about the environment. Amway's world headquarters (and main manufacturing facility) employs about 3500 individuals in a complex of connected buildings over a mile long. Our computer center is near the middle, and houses a large IBM shop (3081 and 3033 processors) in the "big computer room". In the "small computer room" we have one PDP-11/70 and other equipment such as an IBM System 38. The PDP-11/70 is configured with 3 Mb of memory, an RM05 system disk, 3 RA81 user disks and 2 tape drives - TU77 and TE16. The machine has 3 DL single line terminal interfaces, a 16 line DH and enough DZs to bring the total to TT102:#. Two DUP11 interfaces provide Bisync connections to the IBM network for both RJE and 3270 terminal emulation. We use the DEC processor as an in-house timesharing service. It is used primarily by the Research and Development, and Quality Assurance areas. Because it is a timesharing system, we have very little control over the processing load placed on it by the users. To try to make sense of the load, we have defined several classes of users and support. First are the production applications which have been justified, documented, formally reviewed and approved. They have an elevated priority on the machine. Word processing of all the control documents used in our manufacturing processes is one such production application; often there are 8 W/P users active, and half of them are list processing. We use WORD-11 for our production word processing. However, since this is primarily a timesharing system, production applications are usually implemented on the IBM systems. As an example, a daily set of approved new or updated documents is transferred from the 11/70 to the IBM system for recall by the users. Only document maintenance is done on the DEC system. Production applications are those which cover more than one department, or use software purchased from a vendor. Production applications often have their own UFD group, so a user may have several accounts; one for general departmental use, and one or more cross departmental application accounts. Production accounts are backed up more often than the other types of accounts on the system. The next class of user is the departmental user. Each department is a separate UFD group on the system. Departments write and use their own applications. Many tools are available for this, such as BASIC-11, Basic-Plus-2, Fortran 77, Macro-11 and Datatrieve. A variety of editors is also available - EDT V2 and V3, EDI and KED. We also offer FMS-11 to ease screen handling. These users all run at the system default priority, with the editors slightly elevated to improve response time. We run a lot of statistics programs, both SPSS and user-written, and we support a spreadsheet package. None of these users are privileged. Both of these classes of users can receive support for any documented program they wrote, or for any supported system component, by calling our HELP desk. A call to one number resolves hardware problems, report distribution problems or any other problem/question dealing with data processing. The HELP desk functions as a miniature support center, logging the call and assigning it to the proper person for resolution. Management receives daily status reports on all problems, and it has become very convenient for both IBM and DEC users. If the HELP desk support personnel - currently 2 individuals in the EDP Technical Support department - cannot resolve a problem, they take it to DEC or the appropriate vendor for further investigation. We run on the theory that support software is documented, so - if reality and the documentation disagree, one of them needs adjusting. If the software came from a vendor, we report it and let the vendor make the adjustment. (NB: Try to follow the vendor's rules when you do this; they usually know what information they need to correct your problem and they tell you how to report it. If that fails, try other methods.) Remember, if the vendor doesn't know about it, they can't fix it - and you have to live with it. The third class is unsupported, or "mirror image" software - i.e., if you want to see who supports it, look in the nearest mirror. This consists mostly of DECUS software, and includes packages such as TECO, SOS, Pascal, C, Forth and many system utilities. These all run at a priority below the default so that they don't crowd the supported software. The final class is Batch users in the Batch queues. No matter what they are running, if it's at a priority higher than 48 (remember that the default is 50), it is reduced to priority 25. Batch users get whatever time the terminal users aren't using. This minimizes terminal response time. This is done with a monitor developed in-house (available from the DECUS Program Library, order _# 11-792) known as ZZZ. We currently run 3 batch streams. We have over 300 users known to the system, and over 200 of them use the system in any given month. We have modified HELLO to limit the number of logged-on users to 20, excluding batch processes, at any given time. This value was developed from experience. Override accounts are available which allow logons when the system is at max users. This does occasionally cause some trouble at peak times, but it has proved to be a workable solution to insuring relatively good response time once the user is logged on. There are many approaches to system tuning. We base ours on the theory that there are only so many CPU cycles available in a day; and we have days when we use ^&all\& of them. These cycles can be divided into the following categories: .BREAK o##^&Null time\&; the processor is idle .BREAK o##^&User work\&; the CPU is running a user task or utility .BREAK o##^&System work\&; service such as retrieving a file record .BREAK o##^&System overhead\&; overhead such as accounting, task scheduling Null time is something you hope never runs out, because when it does, everything slows down. There are two solutions; add more processing power, or reduce some other component of the total time being used. System overhead is the logical choice because we are trying to maximize user work. Isolating system overhead from system work is not easy. The best solution we have found is to monitor the ratio of user to system state. If the ratio increases after a tuning change, we have reduced system overhead. If it decreases, we have increased it. Because our system is operated around the clock, we usually are forced to determine this ratio statistically rather than by running benchmarks. One of the worst causes of system overhead is the Shuffler. When a memory allocation request fails, the Shuffler is requested to rearrange the tasks in memory to make it possible for the failing request to succeed. Fixing tasks in memory can cause such fragmentation. If you must fix tasks, install them during startup so that they are placed on the lower edge of the GEN partition, or make a separate partition for them. Adding memory to your system is another (more expensive) solution to the problem. Another cause of system overhead is checkpointing. This occurs when a task is temporarily inactive, waiting its turn to execute, and a higher priority task requires memory. This has the effect of copying the lower priority task to disk and restoring it to memory at a later time when memory is available. No productive work is done during this period. The Shuffler uses checkpointing to move tasks about in memory. Another cause of checkpointing is a task extending itself and colliding with another task loaded above it in memory; this causes the task to be checkpointed and reloaded in a new location where the extension can occur. If you expect a task to extend itself, install it with an appropriate increment instead. This prevents checkpointing caused by extension. The Taskbuilder is a good example of a task which extends itself. We find that the file system has overhead which can be reduced. First: Mount each disk with its own ACP. Use the /ACP=UNIQUE switch to do this. This maximizes the amount of buffer space available for each disk and prevents ACP cache flushing. Second: Expand the number of control blocks and buffers in memory by increasing the LRU and WIN counts above the defaults. This is particularly important on big disks with many UFDs. Finally: Look at the ACP taskbuild command file in [1,20] and see if it is possible to enlarge the buffer area following the comments. The ACP goes to primary POOL when it runs out of internal space, so put as much buffer space in the ACP as possible. Another tuning step is to attempt to spread the I/O across all of the devices on the system. Checkpoint files are used in the order allocated, and checkpoints task I/O. Allocate checkpoint space starting with your least used disk; consider reallocating the checkpoint space on the system disk to put it into a less used position to improved task loading by reducing the I/O load on the system disk. Just make sure that you keep one checkpoint space allocated while you reallocate the system disk. Another possibility is to use a logical assignment for each group in the account file and make those logical assignments globally at system startup. This allows you to move a group of users transparently at any time to balance I/O. Yet another approach is to reduce user work and system work in the applications. Preallocate files to prevent the overhead of a file extension while the task is executing. Make sure that you use efficient bucket sizes. Use common sense when designing applications. RMS indexed files must be reorganized periodically, as do entire disk volumes. There are often two ways to ask the system to do something; make sure you are using the more efficient methods. Terminal I/O should also be considered. A DH11 uses DMA output when possible, reducing the number of interrupts that must be services. Put terminals with heavy activity on DH11s if you have them; if not, put them on the first lines of each DZ11. Consider standardizing terminal speeds to reduce bursts of interrupts that make for uneven response time when high speeds are used. We have settled on 4800 baud for production and 2400 for non-production terminals. Users are free to change this (if they know how), but they must do so every time the system is rebooted. Another source of overhead is task loading and overlay loading from disk. If a task is to be used by several users, consider making it a multiuser task with shared code that must be loaded only once. Strive to reduce the number of overlays. We do not have users on the system disk, only support personnel; all software is loaded from the system disk for production applications. This also includes the use of resident libraries to further reduce the size of the code needed to be loaded when the application is run. An additional source of overhead is intertask communication. Some of it is intentional, such as send data directives. There is often nothing to be done about it, but keep it in mind as a source of overhead. Some may be unintentional, such as offspring control blocks. These are created when a task is started and released when the task exits or emits status. They occupy POOL, often causing fragmentation - another source of overhead. If the OCBs are unnecessary, it is possible to emit status to make them go away. The OCB does not go away when the parent task exits. POOL is another source of overhead. If it becomes fragmented, the system must do more work searching for a fragment large enough to service POOL requests. POOL is a limited resource even under RSX-11M-Plus with secondary POOL. Long running tasks such as batch processors and spoolers should be started before there is much activity so that their control blocks sit on the edge of POOL, reducing fragmentation. The round-robin scheduling routines are another source of overhead because of context switching. Don't be afraid to change the interval to a longer time. Use the priority scheme instead. A useful technique for doing this is to compile a list of all the tasks to be run in the system. Rank the list in priority order by asking the question, "If I could only run one task, which task is it?". Move that task to a second list, repeating the process until all tasks are ranked. Don't forget to include the default priority tasks, although it is strongly recommended that the system tasks keep their relative position in the list. Now go through the ranked task list and assign priorities, working up and down from the default, so that task priorities are evenly spaced. Then check whether any heavily used tasks are CPU bound - such as the Taskbuilder - and consider reducing their priority slightly to minimize the impack on terminal users. It's all right if some tasks have the same priority; just don't make the number of tasks with equal priorities too large. Now go back and re-VMR the system. Finally, look for bottlenecks in system performance. Do your disks spend all day hopping about the computer room? Turn on disk optimization or play with the optimization parameters until they perform better. Say that the overlay rate goes up; is it due to one task being run by everyone? If so, see if the task can be flattened, memory overlaid, or broken into two cooperating tasks. Keep good records of system activity for analysis and review. Use RMD and the system accounting files, or use a system monitor such as SPM-11. Feed the raw data into a statistical package and see what comes back. System tuning is a continuous activity. System conditions evolve, and tuning must be adjusted to match the changing demands on the system. Keep records when changes are made. Graph tuning data; look for short and long term cycles. Look for trends; slopes and curves that flatten out usually indicate bottlenecks that can sometimes be widened to allow more throughput. Develop a profile of the average task, and see how it is increasing in sophistication by its growing demands for system resources. RSX is a very robust operating system with many knobs to turn. The task of system tuning is learning how to turn those knobs to make the system play your tune. .COMMENT .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT The Inside Scoop on BRU .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT .TEST PAGE 14 .SKIP 6 .CENTER ^&The Inside Scoop on BRU\& .SKIP .CENTER Steve Realmuto .CENTER Digital Equipment Corporation .CENTER Nashua, NH .SKIP ^IS144^GThe following article is a collection of handouts used during the general session on BRU at the Spring symposium in Dallas. While no supporting text is available, the material is of such interest that the Multi-Tasker is presenting it as it stands. In some areas these figures may be difficult to read; this is because they are second generation copies of the handouts and not reproduced from the originals. --- The Editor^IS204^G .PAGE .NONUMBER .LM 0 ^PN^-