Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Design

Letters


AUG94: LETTERS

More on Memory Management

Dear DDJ,

In "Rethinking Memory Management" by Arthur Applegate (DDJ, June 1994), there was a discussion and example of overloading operator new on a per-class basis. Applegate's purpose was to call a fixed-size memory allocator that would efficiently allocate memory of size sizeof(MyClass). Using a fixed-size memory allocator where the memory pool is only for memory allocations of a particular size is faster than using a general-purpose allocator which may be called with any size.

What the example did not show was that an overloaded operator new in a class that calls a fixed-size allocator should test that the size being requested is indeed equal to sizeof(MyClass). Why? Because if someone inherits from that class, they could be reserving a fixed size of memory that is too small for the inherited class.

If all the inherited classes also overload operator new, you can avoid the problem. But if any inherited class forgets to include an operator new for that size class, then you have a problem. Without it, the operator new of the base class will be called, and the wrong amount of memory will be allocated. Fixing the code in the base class is easy; see Example 1(a).

Even if no one is inheriting from MyClass now, someone might inherit from it in the future, and memory corruption would occur. It's safest to include a check of the requested size before doing the actual memory allocation, even if inherited classes have their own fixed size new or if you don't intend to inherit from the class.

Since operator new can call either a fixed-size memory allocator or a general- purpose allocator, the delete routine must reflect that change. The operator delete function has an optional, two-argument style, as in Example 1(b). Only one operator delete may be declared for a single class. The proper operator delete for MyClass becomes Example 1(c).

Steve Simpson

N. Billerica, Massachusetts

Processor Perspective

Dear DDJ,

The article, "Computer Science and the Microprocessor" by Nick Treddenick (DDJ, June 1993) was one of the best big-picture, see-the-forest-and-the-trees articles I have had the pleasure of reading. In the text box, "CPU Performance: Where Are We Headed?" Tredennick suggests that a "reconfigurable-logic-unit" (RLU) built into future microprocessors might be what's needed to maintain CPU speed increases after clock rates, parallel pipes, and so on "hit the wall."

Why wait? The September 1991 Byte magazine carried an article describing a PC add-on that carries reconfigurable logic chips that can be programmed (that is, configured) by the host CPU, then run in the manner of a coprocessor. Just as Nick describes, but with off-chip RLU. These cards are made by the Scottish company Algotronix Ltd.

But why use reconfigurable logic just as a coprocessor? In the February 1991 issue of Electronics World + Wireless World, I proposed a computer architecture, which I dubbed the "Impulse Matrix," based entirely on such reconfigurable hardware. (Unfortunately, the newly appointed editor of that magazine so butchered the article that much of the argument was lost--my letter in the May 1991 issue of EW+WW attempts to clarify some of the distortions.)

Briefly, the Impulse Matrix consists of a rectangular grid of cells, each containing writable configuration bits together with some "active" logic functions and "passive" wiring functions. Writing to the configuration bits of a cell sets that cell to some logic function (that is, the North output is the XOR of the East and West inputs) or, more simply, the cell is configured as a wire (all inputs and outputs are disconnected--the simplest wire). Set the configuration bits of many adjacent cells, and the computer takes on the function of any conceivable digital circuit. If you have enough cells (even 1980s technology would allow millions of cells) you could have, for example, an 80x86, a 680x0, a DSP, and a graphical engine in the four corners of the matrix and the OS of your choice tying them together in the middle.

Some of the advantages of such an architecture are as follows:

  1. The architecture resembles a normal computer with the CPU removed. There would be a vestigial, extremely simple (1-bit?) CPU and ROM whose only function is to boot the system on start-up/reset and provide some I/O buffers, mass storage, power supplies, and such. But mostly, the computer would be row upon row of simple, cheap "memory" chips and no complex, expensive CPU. The economies of scale and scalability of required computer power are obvious.
  2. Only about 0.1 percent of the silicon in today's computers does any computing. A typical post-1960 computer is 99 percent idle memory and 1 percent CPU. But 90 percent of the CPU, the registers, microcode, and, these days, the ever-larger caches, are also just idle memory. It is only the ALU (or integer and FP pipes) that actually does any active date processing; hence an efficiency of 0.1 percent. It is my guess that the matrix architecture would be about 10 percent efficient. That is, 90 percent of the silicon would be devoted to the configuration circuitry and 10 percent to the execution circuit.
  3. The matrix architecture is ideally suited to multitasking or parallel computing. Rather than time slicing on a serial CPU, the matrix can be "space" sliced into different functional blocks that operate together in real time.
There are other advantages, such as testability and fault tolerance; unfortunately, there is not the space to cover these here.

There is also a catch.The catch is that you would be wasting your time if you tried to program the matrix with a language (though many people will try). Low level, high level, procedural, nonprocedural, object oriented, whatever: Languages are just not up to the job of designing digital circuits. The correct and tried and tested method of "programming" these circuits is via circuit schematics.

The language-versus-schematic debate is the crux of the reconfigurable logic debate. I must stress that this new architecture cannot be introduced simply as new hardware. If the hardware is to be used successfully, then it must come with programming tools, and to be at all workable, those tools must use some sort of a schematic programming system.

For a long time I have been of the opinion that languages are not even well suited to programming von Neumann computers. It has only been for the last 40 years, and only in the field of computer software, that any engineering design has been done exclusively with languages as the medium. Every other engineer uses either two-dimensional drawings or three-dimensional models.

The problem with languages is that they are essentially one-dimensional. That is, you can only say or do one word or instruction at a time. The instructions in today's programs are usually arranged one-dimensionally, one after another, in an untidy column down the page--the ragged left margin supposedly giving the program a "structure." A circuit schematic is 2-D, and it is understood that you can read (or look at) any part of the schematic in any order. For a language to make sense, you must start at the beginning and work steadily through to the end (clearly, programs don't run steadily from BEGIN to END--the main reason why languages are not suited to programing). The 2-D "all-at-once" schematic has an inherent parallelism, making it suited to parallel execution. One-dimensional languages are inherently sequential and, as a result, have been a great hindrance to creating parallel applications.

Okay, but what about all those structured, modular, object-oriented, high-level languages? Well, if you think about the adjectives used in the last sentence, or those used to describe most modern languages, they can all be used more aptly, to describe schematics. A high-level, modular, schematic object is a box with "686 Engine" written on it.

So far, I have compared languages to old-fashioned paper schematics. On a VDU, a schematic can be made to move, and the impulses can be shown propagating along the wires. The schematic becomes 3-D, making it even more powerful. The map becomes even more like the terrain.

I could go on and on but I think the best argument is history itself.

Take PCs, for instance. Over about 20 years, the hardware (designed using schematics) has gone from 8-bit through 16-bit and 32-bit to 64-bit CPUs. Some of these CPUs had bugs in them when first released, but invariably they were bug free within a year.

So where is today's 64-bit software? Where is the 32-bit software? Well, there is some 32-bit software around but mostly we still use mid-1980s, 16-bit software. It's a slow business, this software business.

And bugs! Even the 16-bit software that has been through the code/test/debug cycle for the past ten years is bug ridden. This just does not happen in the hardware industry. You would lose your job if you couldn't debug your circuit after the first few iterations.

The software-bug situation is so bad some programmers boast that their code is so big and complex that it will inevitably have hundreds of bugs. Bugs have become a sort of programming badge of merit. As an engineer, I find this disgraceful.

Erik Zapletal

Beaconsfield, Australia

Microkernels and Operating Systems

Dear DDJ,

Congratulations on Peter Varhol's article (DDJ, May 1994) surveying the state of operating-system technology. Although the overview of QNX provided some very good detail, we'd like to expand on a few of his points.

First of all, Varhol argues that message passing represents more overhead than a "function call" to invoke an OS service and therefore can slow down a microkernel OS . The function call he's referring to here is really the monolithic OS kernel call, which is much more complex than a simple function call. In order to provide reentrancy, a monolithic kernel must implement semaphores and preemption points, ultimately adding complexity. In contrast, a microkernel OS moves system services off into other processes, so it can provide a very clean and fast code path for implementing the message pass. Once message passing becomes sufficiently fast, the overhead issue is irrelevant, since the work requested dwarfs the time it took to make the request (see "The Increasing Irrelevance of IPC Performance for Microkernel-Based Operating Systems," by Brian N. Bershad, Proceedings of the Usenix Workshop on Micro-Kernels & Other Kernel Architectures, Seattle, WA, April 1992). Having implemented greater concurrency and reentrancy, a microkernel OS can provide better overall performance.

A fast, message-passing OS also benefits client/server computing, where the ability to perform fast IPC between communicating processes is essential. We've taken the microkernel concept a step further and used QNX's fast message passing to implement the first "microkernel GUI" for handheld and embedded windowing environments.

Varhol states that "QNX claims to perform at least as well as traditional architectures." Actually, we make an even bolder claim: QNX outperforms most traditionally architected operating systems. To back this up, we invite interested readers to ftp the file /pub/papers/qnx-paper.ps.z from quics.qnx.com (198.231.78.1), which contains further details on the microkernel/monolithic-kernel performance issue, including benchmark results.

Incidentally, the mention of Windows NT as a "microkernel operating system'' is surprising, given that Microsoft's Dave Cutler stated emphatically at the 1992 Usenix Workshop on Micro-Kernels & Other Kernel Architectures in Seattle that Windows NT is not a microkernel OS!

Dan Hildebrand

QNX Software Systems Ltd.

Kanata, Ontario

Example 1: More on memory management.

(a)   void* MyClass::operator new(size_t size)
      {
        if (size == sizeof(MyClass))
        {
            // allocate from fixed size memory pool
        }
        else
        {
            // call global new for inherited class of any size
            return ::operator new(size);
        }
(b)   void operator delete (void*, size_t);
(c)   void MyClass::operator delete(void *p, size_t size)
      {
        if (size == sizeof(MyClass))
        {
            // delete from fixed size memory pool
        }
        else
        {
            // call global delete for inherited class of any size
            ::operator delete(p, size);
        }
      }


Copyright © 1994, Dr. Dobb's Journal


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.