home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / mach / doc / published / IPCperf.doc.Z / IPCperf.doc
Encoding:
Text File  |  1992-09-09  |  27.0 KB  |  532 lines

  1.  
  2.           The Increasing Irrelevance of IPC Performance for Microkernel-Based
  3.                               Operating Systems
  4.  
  5.  
  6.  
  7.  
  8.                                Brian N. Bershad
  9.                            School of Computer Science
  10.                            Carnegie Mellon University
  11.                               5000 Forbes Avenue
  12.                              Pittsburgh, PA 15213
  13.  
  14.                            Brian.Bershad@cs.cmu.edu
  15.  
  16.  
  17.                                 March 10, 1992
  18.  
  19.  
  20.  
  21.  
  22.  
  23.                                   Abstract
  24.  
  25.  
  26.                IPC is the glue with which traditional operating system
  27.             services such as networking, and filing, are provided in
  28.             microkernel-based operating systems. Because applications
  29.             rely heavily on cross-address space communication, IPC
  30.             performance is often viewed as being the ``Achilles heel'' of
  31.             a microkernel-based operating system. In this paper I discuss
  32.             four reasons why IPC performance is becoming increasingly
  33.             irrelevant to overall system performance.
  34.  
  35.             1 Introduction
  36.                Microkernels such as V [Cheriton 84], Chorus [Rozier et al.
  37.             88], and Mach [Accetta et al. 86] provide the infrastructure
  38.             with which other operating systems such as Unix, MS-DOS and
  39.             VMS can be implemented as user-level programs [Golub et al.
  40.  
  41.           ()This research was sponsored in part by The Defense Advanced
  42.          Research Projects Agency, Information Science and Technology Office,
  43.          under the title ``Research on Parallel Computing'', ARPA Order No.
  44.          7330, issued by DARPA/CMO under Contract MDA972-90-C-0035 and in part
  45.          by the Open Software Foundation (OSF), and a National Science
  46.          Foundation Presidential Young Investigator Award.
  47.           ()
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.                                      1
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.             90, Rashid et al. 91, Cheriton et al. 90, Wiecek 92].
  63.             Because applications use cross-address space IPC to interact
  64.             with traditional operating system services, IPC performance
  65.             has been thought to be the Achilles heel of microkernel-based
  66.             systems. Even with the improvements in IPC performance that
  67.             have occurred in the past 5 years [Bershad et al. 90, Draves
  68.             et al. 91], microkernel based systems are still believed to
  69.             have inherently worse performance than their monolithic
  70.             counterparts. This belief stems from the fact that the system
  71.             call, which is the mechanism for interacting with monolithic
  72.             operating systems, such as 4.3BSD [Leffler et al. 89] and
  73.             Sprite [Ousterhout et al. 88], is faster than a cross-address
  74.             space IPC, which is how applications interact with user-level
  75.             operating system services.
  76.                Although IPC latency in microkernels is slower than system
  77.             call latency, the absolute difference between them has reached
  78.             the point where it can be largely ignore<d. In other words,
  79.             IPC performance is becoming increasingly irrelevant as a
  80.             metric with which to assess microkernel viability.
  81.                There are four reasons that IPC performance should no
  82.             longer be a principal metric by which one judges the
  83.             ``goodness'' of a particular operating system microkernel, or
  84.             even a particular approach to building operating system
  85.             microkernels. In brief, these reasons are:
  86.             1. IPC has gotten faster faster than the rest of the operating
  87.                system.
  88.  
  89.             2. Performance is dominated by caches, not by address spaces.
  90.  
  91.             3. All data does not need to be marshalled through the kernel.
  92.  
  93.             4. All services do not need a hardware firewall.
  94.                The first two reasons stem from the ever-growing
  95.             performance imbalances which exist in today's systems. Simply
  96.             stated, IPC mechanisms are not the performance bottlenecks
  97.             which they once were. Instead, there are other, more
  98.             fundamental bottlenecks, such as memory transfer speed,
  99.             network latencies, disk speed, and cache management overhead.
  100.             The second two reasons are due to the maturity which
  101.             microkernel-based systems have achieved in the last few years.
  102.             Specifically, in their efforts to increase performance,
  103.             systems builders have discovered a collection of techniques
  104.             which can be used to bypass, or at least ``dance around'' IPC
  105.             facilities.
  106.                In the rest of this paper I expand on the reasons listed
  107.             above, and discuss why we should stop measuring microkernel
  108.             systems by the speed of their round trip IPC times. I present
  109.             examples and observations from the Mach 3.0 microkernel
  110.             running on a collection of architectural platforms to motivate
  111.             and substantiate the discussion.
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118.  
  119.             2  IPC Has Gotten Faster Faster Than the Rest of The
  120.             Operating System
  121.                It has been observed that operating system performance has
  122.             improved far less rapidly than would be expected given
  123.             improvements in processor architecture and
  124.             implementation [Ousterhout 90, Anderson et al. 91]. Although
  125.             the time to add two registers together has decreased by almost
  126.             two orders of magnitude in the last decade, the performance of
  127.             key operating system services, such as filing, paging, and
  128.             networking, has remained relatively flat. Disks continue to
  129.             spin at about the same speed as they always have, buffer
  130.             caches remain limited by memory bandwidth, and core network
  131.             latency remains on the order of several hundred microseconds
  132.             (although network bandwidth has improved somewhat more
  133.             dramatically).
  134.                In contrast to the performance of the services which are
  135.             being provided by the operating system, the time to send a
  136.             message between two address spaces on the same machine has
  137.             dropped substantially. The reasons for this are two-fold.
  138.             First, we've become more careful and more successful at
  139.             building IPC mechanisms ``for speed,'' ruthlessly streamlining
  140.             and optimizing the common cases. Using the Mach 3.0
  141.             microkernel as an example, IPC performance on a Microvax-III
  142.             (CVax processor) has gone from about 750 XXsecs for a
  143.             round-trip RPC in 1989 [Bershad 90] to 497 XXsecs in 1992
  144.             (measured recently using Mach 3.0 version MK68). The
  145.             improvements were due to tightening the interface [Draves 90],
  146.             and the implementation [Draves et al. 91].
  147.                The second reason why IPC has gotten faster faster than the
  148.             rest of the operating system is that measured IPC performance
  149.             has, at least to this point, tracked processor performance
  150.             reasonably well.(1) In Mach, this is largely because the
  151.             improvements made in the last several years have moved IPC
  152.             performance off of the memory curve and onto the processor
  153.             curve by tightening the locality of the IPC paths. Again,
  154.             using Mach 3.0 MK68, a round-trip RPC takes 57 XXsecs(2) on a
  155.             DecStation 5000/200. That system, which uses a MIPS R3000
  156.             processor running at 25Mhz, is rated at roughly ten times the
  157.             performance of the CVax. In keeping with this, cross-address
  158.             space RPC is about nine times faster than the same code
  159.             running on a CVax.
  160.                With IPC performance improving more rapidly than general
  161.             operating system service performance, the ``hit'' required to
  162.             access such a service is becoming less important. For
  163.             example, on the older CVax, the 497 XXsecs required to do a
  164.  
  165.          (1)Although IPC performance is ultimately limited by architectural
  166.          features such as trap and context switch time, and although these
  167.          times have not been improving at the same rate as processor
  168.          speed [Anderson et al. 91], practical IPC performance has not yet
  169.          reached this limit.
  170.          (2)All times were measured with warm caches.
  171.  
  172.  
  173.  
  174.  
  175.  
  176.  
  177.  
  178.             cross-address space RPC was comparable to the time it took
  179.             seek one disk track, or copy a 512 byte block from a system
  180.             buffer cache into a user buffer, or to transmit a packet over
  181.             an Ethernet. On the DecStation 5000/200, however, the IPC
  182.             penalty is substantially less. Since disk access, data
  183.             transfer, and network latencies have not improved at anywhere
  184.             the same rate, the additional cost of the IPC required to
  185.             indirect to these facilities has become less significant.
  186.  
  187.             2.1 System Calls Are Not The Solution
  188.                System calls used in monolithic kernels are the alternative
  189.             to the IPC mechanisms used in microkernels. Monolithic
  190.             operating system services reside in the kernel, and are
  191.             accessed by applications with a single kernel boundary
  192.             crossing. On older systems, such as the CVax, the time to
  193.             execute a Mach system call(3) was about 60 XXsecs,
  194.             substantially less than the IPC overhead (497 XXsecs) on that
  195.             machine. In contrast, on the newer DecStation 5000/200,
  196.             system call overhead is about 8 XXsecs, or about 50 XXsecs less
  197.             than a round-trip RPC. While the relative cost of IPC and
  198.             system calls on the two machines is the same, the absolute
  199.             difference compared to the service access cost (disk, buffer,
  200.             or network), is much smaller. As a result, there is
  201.             diminishing incentive to use system calls, rather than
  202.             generalized IPC facilities, to access system services.
  203.  
  204.             3 Performance is Dominated By Caches, Not by Address Spaces
  205.                The invocation of an operating system service implies a
  206.             change in locality. In monolithic systems, the new locality
  207.             is in the kernel. In microkernel-based systems, the new
  208.             locality is in another address space. In both cases, however,
  209.             the change in locality can result in an increased cache miss
  210.             rate [Agarwal et al. 88, Mogul & Borg 91]. On older style,
  211.             slower architectures (< 10 MIPS), cache miss penalties were
  212.             only a few cycles. On today's architectures, however, cache
  213.             miss penalties are tens, and soon to be hundreds, of cycles.
  214.             These kinds of penalties can easily dwarf the kernel's IPC
  215.             overhead. In effect, the cost of accessing an operating
  216.             system service is going to be most influenced by whether or
  217.             not that service is in the cache -- not whether or not it's in
  218.             the kernel or in another address space.
  219.                One could argue, however, that OS interaction via a
  220.             microkernel actually involves two changes in locality -- one
  221.             to the microkernel and another to the server. While true, the
  222.             microkernel's locality (at least on the critical path through
  223.             to the operating system server) is small. The common-case
  224.             round trip IPC path in Mach 3.0 on the MIPS, for example,
  225.             requires less than 4KB of instructions and references less
  226.             than 2KB of data, most of which is on the kernel stack.
  227.             Because the locality is small, and identifiable a priori, one
  228.  
  229.          (3)Mach, although a microkernel, does export a small number of
  230.          ``true'' system calls.
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238.             could decrease the chance that misses occur on the IPC path by
  239.             allocating memory with an eye towards the cache hashing
  240.             function [Bershad et al. 92]. For virtually addressed
  241.             caches, this means devoting pieces of the machine's virtual
  242.             address space to the microkernel. For a physically addressed
  243.             cache, physical memory must be devoted, although one can play
  244.             tricks with split instruction and data caches to ensure that
  245.             only data pages conflict with designated instruction pages,
  246.             and vice versa.
  247.                One place where cache performance becomes apparent is in
  248.             the management of external devices which use DMA, and not
  249.             programmed, I/O. Before the processor reads memory into which
  250.             DMA has been performed, it must purge that memory from the
  251.             cache to ensure that stale data is not returned. Before a
  252.             processor issues a write request to a DMA device, it must
  253.             flush the memory to be written from the cache, again to ensure
  254.             that stale data is not read by the device. These cache
  255.             operations are expensive. For example, on the HP-700, a high
  256.             performance workstation based on the HPPA RISC processor with
  257.             a cycle time of 20 nanoseconds, cache purge and flush
  258.             operations take between 1 and 14 cycles per line (32 bytes),
  259.             DMA operations tend to be page-oriented, so I/O operations
  260.             require between 128 and 896 cycles simply to ensure memory
  261.             coherency. In the case of device reads, performance degrades
  262.             even further as the newly transferred data is faulted into the
  263.             cache, at a cost of 16 cycles per line (2048 cycles per page).
  264.             In contrast, a cross-address space RPC in Mach 3.0 on that
  265.             machine takes about 70 XXsecs (3600 cycles). Consequently, the
  266.             cost of accessing an out-of-kernel device server (changing
  267.             address spaces) represents only one component of the total
  268.             CPU/device communication cost.
  269.  
  270.             4 All Data Does Not Need to be Marshalled Through the Kernel
  271.                Microkernel-based operating systems can preallocate buffers
  272.             between client and server address spaces. This allows an
  273.             operating system service to share address space with
  274.             applications, just as it did when the service was resident in
  275.             the kernel. Small to medium amounts of data can be
  276.             transferred from one address space to another by depositing it
  277.             in the shared regions, rather than by sending it through the
  278.             kernel in a message [Bershad et al. 91]. Large data segments
  279.             (on the order of pages) can be passed using virtual memory
  280.             primitives.
  281.                Co-mapping of IPC data has been used in several places. At
  282.             CMU, applications share memory with the Unix server to pass
  283.             data in and out of the file system. We have recently applied
  284.             this technique to the socket interface as well.   On a
  285.             DS5000/200, we have found that the mapped socket interface
  286.             does not improve the performance on small packets (fewer than
  287.             100 bytes), but in larger packets there is an improvement.
  288.             For packets of 4KB, sends using the mapped socket interface
  289.             are 15% faster than using the regular, non-mapped, interface.
  290.             In packets of more than 4KB the mapped interface avoids the
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.             cost of dynamically allocating and deallocating the region for
  299.             out-of-line transmission, although for extremely large packets
  300.             remapping, rather than copying, is more efficient.
  301.                Co-mapping can be used effectively for non-Unix interfaces
  302.             as well. For example, we have built a version of the X11
  303.             window server which uses Mach IPC for communication between X
  304.             clients and the server. X does call request buffering, but
  305.             clients frequently flush the buffer, which causes the data to
  306.             be made available to the server. When Unix stream sockets are
  307.             used to implement the transport layer, the flush causes a
  308.             socket write to occur. With sockets, multiple flushes may
  309.             occur before the server collects any of the data, but all of
  310.             the data can be collected in one receive, so transferring data
  311.             through the kernel doesn't necessarily increase the number of
  312.             context switches. When using Mach's IPC, which is
  313.             message-oriented, every flush results in a message. Message
  314.             boundaries are maintained, so every message must be collected
  315.             separately by the X server, increasing the the number of
  316.             user-kernel boundary crossings and context switches relative
  317.             to a socket-based implementation. We are modifying the X
  318.             library to buffer requests in shared memory. Flushes transfer
  319.             the data to the shared buffer, and only cause an IPC message
  320.             to be sent if previous IPC messages have not yet been
  321.             collected.
  322.  
  323.             5 All Services Do Not Need a Hardware Firewall
  324.                The cost of accessing functions in another protection
  325.             domain (whether in the kernel or in a server's address space)
  326.             has provided motivation for microkernel-based systems to
  327.             migrate what were once kernel functions into client address
  328.             spaces. This is possible when unprotecting the functions has
  329.             no security implications. For example, there's no reason to
  330.             put the system clock in the kernel, let alone another address
  331.             space -- on most architectures, the clock can be mapped
  332.             directly into user address spaces. Similarly, network
  333.             protocols can execute in the address spaces of the
  334.             applications which are communicating rather than in the kernel
  335.             or a special protocol server [Schroeder & Burrows 90, Maeda &
  336.             Bershad 92]. Applications can send and receive packets
  337.             directly through the network interface. If the network is
  338.             assumed to be insecure (as is generally the case), then
  339.             executing the protocols in a secure protection domain offers
  340.             no additional integrity. Encryption, and not hardware
  341.             protection modes, are necessary here.
  342.                Another technique for removing hardware firewalls is to
  343.             migrate pieces of the operating system service into clients'
  344.             address spaces. Mach's Unix emulation package uses this
  345.             approach with its transparent emulation library, which is a
  346.             shared library mapped into every Unix address space. Unix
  347.             system calls are reflected out of the kernel into the caller's
  348.             emulation library. There, the emulation library may simply
  349.             forward the system call onto the Unix server, or it may
  350.             implement the call itself, if possible. For example, the
  351.  
  352.  
  353.  
  354.  
  355.  
  356.  
  357.  
  358.             emulation library uses a mapped file interface for
  359.             communicating with the Unix server. Read and write system
  360.             calls are intercepted by the emulation library and converted
  361.             into loads and stores to the mapped memory which backs the
  362.             file. In this way, binary compatibility with Unix is
  363.             maintained, and cross-address space IPC is avoided. This
  364.             approach has been generalized in the Mach multiserver
  365.             project [Julin et al. 91], and has resulted in substantial
  366.             IPC reductions. In benchmarks on that system, which are
  367.             intended to be persuasive but not conclusive, client-side
  368.             emulation permits two out of three system calls to be
  369.             implemented without an RPC.
  370.  
  371.             6 Conclusions
  372.                IPC performance has come a long way in the last ten years.
  373.             We now understand how to build IPC mechanisms which are only a
  374.             few tens of microseconds slower than system calls. While this
  375.             may at first seem unacceptably high, an examination of the
  376.             other issues in operating system performance reveals that the
  377.             additional overhead is small compared to the services which
  378.             are being accessed. Moreover, the growing mismatch between
  379.             cache and memory speed is making the physical location of
  380.             operating system code and data much more important than the
  381.             software path by which it is accessed. Finally, as
  382.             microkernel-based operating systems have matured, useful
  383.             techniques which reduce the frequency of operating system
  384.             interaction, and hence, IPC, have also been developed. For
  385.             these reasons, the raw performance of IPC facilities is
  386.             largely becoming an irrelevant metric by which to judge
  387.             microkernel-based operating systems.
  388.  
  389.             Acknowledgements
  390.                Jose Carlos Brustoloni, Rich Draves, Dan Julin, Mark
  391.             Stevenson, and Bob Wheeler supplied most of the measurements
  392.             presented in this paper. Conversations with these people, as
  393.             well as with Bob Baron, Joe Barrera, Alessandro Forin, Michael
  394.             Ginsberg, Chris Maeda and Dan Stodolsky contributed to this
  395.             paper.
  396.  
  397.             References
  398.             [Accetta et al. 86] Accetta, M. J., Baron, R. V., Bolosky, W.,
  399.                    Golub, D. B., Rashid, R. F., Tevanian, Jr., A., and
  400.                    Young, M. W. Mach: A New Kernel Foundation for UNIX
  401.                    Development. In Proceedings of the Summer 1986 USENIX
  402.                    Conference, pages 93--113, July 1986.
  403.  
  404.             [Agarwal et al. 88] Agarwal, A., Hennessy, J., and Horowitz,
  405.                    M. Cache Performacne of Operating System and
  406.                    Multiprogramming Workloads. ACM Transactions on
  407.                    Computer Systems, 6(4):393--431, November 1988.
  408.  
  409.             [Anderson et al. 91] Anderson, T., Levy, H., Bershad, B., and
  410.                    Lazowska, E. The Interaction of Architecture and
  411.  
  412.  
  413.  
  414.  
  415.  
  416.  
  417.  
  418.                    Operating System Design. In Proceedings of the Fourth
  419.                    Symposium on Architectural Support for Programming
  420.                    Languages and Operating Systems, pages 108--121,
  421.                    April 1991.
  422.  
  423.             [Bershad 90] Bershad, B. N. High Performance Cross-Address
  424.                    Space Communication. PhD dissertation, University of
  425.                    Washington, Department of Computer Science and
  426.                    Engineering, Seattle, WA 98195, June 1990.
  427.  
  428.             [Bershad et al. 90] Bershad, B. N., Anderson, T. E., Lazowska,
  429.                    E. D., and Levy, H. M. Lightweight Remote Procedure
  430.                    Call. ACM Transactions on Computer Systems,
  431.                    8(1):37--55, February 1990. Also appeared in
  432.                    Proceedings of the 12th ACM Symposium on Operating
  433.                    Systems Principles, December 1989.
  434.  
  435.             [Bershad et al. 91] Bershad, B. N., Anderson, T. E., Lazowska,
  436.                    E. D., and Levy, H. M. User-Level Remote Procedure
  437.                    Call. ACM Transactions on Computer Systems,
  438.                    9(2):175--198, May 1991.
  439.  
  440.             [Bershad et al. 92] Bershad, B. N., Forin, A., and Draves, R.
  441.                    Cache Effects for a Microkernel Operating System.
  442.                    Technical report, School of Computer Science,
  443.                    Carnegie Mellon University, 1992. In preparation.
  444.  
  445.             [Cheriton 84] Cheriton, D. R. The V Kernel: A Software Base
  446.                    for Distributed Systems. IEEE Software, 1(2):19--42,
  447.                    April 1984.
  448.  
  449.             [Cheriton et al. 90] Cheriton, D. R., Whitehead, G. R., and
  450.                    Sznyter, E. W. Binary Emulation of Unix using the V
  451.                    Kernel. In Summer 1990 Usenix Conference Proceedings,
  452.                    1990.
  453.  
  454.             [Draves 90] Draves, R. P. A Revised IPC Interface. In
  455.                    Proceedings of the First Mach USENIX Workshop, pages
  456.                    101--121, October 1990.
  457.  
  458.             [Draves et al. 91] Draves, R. P., Bershad, B. N., Rashid,
  459.                    R. F., and Dean, R. W. Using Continuations to
  460.                    Implement Thread Management and Communication in
  461.                    Operating Systems. In Proceedings of the 13th ACM
  462.                    Symposium on Operating Systems Principles, pages
  463.                    122--136, October 1991.
  464.  
  465.             [Golub et al. 90] Golub, D., Dean, R., Forin, A., and Rashid,
  466.                    R. Unix as an Application Program. In Proceedings of
  467.                    the Summer 1990 USENIX Conference, pages 87--95, June
  468.                    1990.
  469.  
  470.             [Julin et al. 91] Julin, D. P., Chew, J. J., Stevenson, J. M.,
  471.  
  472.  
  473.  
  474.  
  475.  
  476.  
  477.  
  478.                    Guedes, P., Neves, P., and Roy, P. Generalized
  479.                    Emulation Services for Mach 3.0: Overview,
  480.                    Experiences and Current Status. In Proceedings of the
  481.                    1991 Usenix Mach Workshop, November 1991.
  482.  
  483.             [Leffler et al. 89] Leffler, S., McKusick, M., Karels, M., and
  484.                    Quarterman, J. The Design and Implementation of the
  485.                    4.3BSD UNIX Operating System. Addison-Wesley,
  486.                    Reading, MA, 1989.
  487.  
  488.             [Maeda & Bershad 92] Maeda, C. and Bershad, B. N. Networking
  489.                    Performance for Microkernels. In Proceedings of the
  490.                    Third Workshop on Workstation Operating Systems,
  491.                    April 1992.
  492.  
  493.             [Mogul & Borg 91] Mogul, J. and Borg, A. The Effect of Context
  494.                    Switches on Cache Performance. In Proceedings of the
  495.                    Fourth Symposium on Architectural Support for
  496.                    Programming Languages and Operating Systems, pages
  497.                    75--84, April 1991.
  498.  
  499.             [Ousterhout 90] Ousterhout, J. K. Why Operating Systems Aren't
  500.                    Getting Faster As Fast As Hardware. In Proceedings of
  501.                    the summer 1991 USENIX Conference, pages 247--256,
  502.                    June 1990.
  503.  
  504.             [Ousterhout et al. 88] Ousterhout, J., Cherenson, A., and
  505.                    Douglis, F. The Sprite Network Operating System.
  506.                    IEEE Computer Magazine, 21(2):23--36, February 1988.
  507.  
  508.             [Rashid et al. 91] Rashid, R. F., Malan, G., Golub, D., and
  509.                    Baron, R. DOS as a Mach 3.0 Application. In
  510.                    Proceedings of the 1991 Usenix Mach Workshop, pages
  511.                    27--40, November 1991.
  512.  
  513.             [Rozier et al. 88] Rozier, M., Abrossimov, V., Armand, F.,
  514.                    Boule, I., Giend, M., Guillemont, M., Herrmann, F.,
  515.                    Leonard, P., Langlois, S., and Neuhauser, W. The
  516.                    Chorus Distributed Operating System. Computing
  517.                    Systems, 1(4), 1988.
  518.  
  519.             [Schroeder & Burrows 90] Schroeder, M. D. and Burrows, M.
  520.                    Performance of Firefly RPC. ACM Transactions on
  521.                    Computer Systems, 8(1):1--17, February 1990.
  522.  
  523.             [Wiecek 92] Wiecek, C. A Model and Prototype of VMS Using the
  524.                    Mach 3.0 Kernel. In Proceedings of the 1992 Usenix
  525.                    Microkernel Workshop, April 27--28 1992. This issue.
  526.  
  527.  
  528.  
  529.  
  530.  
  531.  
  532.