Monday, July 6, 2009

COSA: A New Kind of Programming, Part VI

[Repost. See previous post for an update]

Part I, II, III, IV, V, VI


In Part V, I came out against the use of messaging for common communication between components and showed my preference for the flexibility of reactive data sensing and data connectors. In this post, I describe a new approach to task prioritization based on a simple extension to the COSA behavior control mechanism.

Thread-Based Prioritization

One of the few advantages of using multithreading is that it makes it possible to prioritize threads. Even though this capability will not matter much with the advent of processors sporting hundreds or thousands of cores, the fact remains that, whenever processing power is at a premium, it makes sense to allocate more of the processor’s cycles to critical functions that must execute in real time. It goes without saying that thread-based priority scheduling wreaks havoc with deterministic timing, which is one of the reasons that the COSA software model does not use threads.

Message-Based Prioritization

Since COSA is not multithreaded, my initial approach was to use a message-based scheme for task prioritization. Lately, however, I have been having serious doubts about the suitability of messaging for inter-component communication. The approach that I originally had in mind would use a prioritized message queue within a client-server context. High priority messages would simply go to the head of the queue. It then occurred to me that a queued client-server approach makes no sense in an inherently parallel environment. Indeed, why have a serial server processing queued requests one at a time when using multiple parallel server clones could scale in performance as the number of processor cores is increased? Not a good idea.

Behavior-Based Prioritization

I have already explained how basic behavior control is done in COSA. While the Stop command can be used at times to save cycles, this is not its main intended function. Its main function is to prevent conflicts among cooperating components. Besides, an improperly timed Stop command will probably result in failure because intermediate results are discarded. I figure that the best way is to introduce a new control mechanism that can temporarily pause a component. I call it the Pause Effector. Its purpose is to give the system the ability to alleviate the processor’s load so that the more time-critical tasks can be processed in real time. The caveat is that any signal received by the component during its comatose state will be ignored.
The way it works is as follows. When a signal arrives at the ‘Pause’ terminal, the component goes into a coma and all cell activities in the component are suspended. Internally, the system sets a ‘stop’ flag in all the cells that causes the processor to stop processing them. All cells that were about to be processed in the next cycle are placed in a temporary hold buffer. On reception of a ‘Continue’ signal, the system clears the ‘stop’ flag in all the cells and the cells that were in the temporary hold buffer are transferred into the processor’s input buffer for processing. A signal is emitted to indicate that the component is once again active.

Load Manager

At this point, I believe that the Pause effector should not be directly accessible by user applications. Every COSA operating system will have a Load Manager whose job it is to manage processor load according to every component’s load requirement. My current thinking is that only the Load Manager should control the Pause Effector but this may change if a good enough reason is brought to my attention. Again, I will say that I don’t think that task prioritization will be needed in the future with the advent of processors with hundreds and even thousands of cores.

In a future article, I will introduce the COSA Connection Manager, a special COSA system component that makes it possible for a component to modify its programming on the fly. This is essential for certain adaptive applications like neural networks and other machine learning programs.

Related article:
How to Solve the Parallel Programming Crisis


Josh McDonald said...

Thought I'd drop in to say I'm glad you're heading back to topics I'm (almost) capable of following, and that we're still out here reading.

Oh, and don't worry, you're definitely still a crackpot =]

sprucely said...

Something I don't understand is the statement you (Louis) have made in the past that the COSA processor only knows about cells and synapses, and that the concept of components is simply organizational for the benefit of the developer and development tools.

But there are concepts that imply that COSA does or should know about components. In the current model, effectors that are intended to effect entire components, such as Pause or Dup & Launch, could need to be "wired" to thousands or tens of thousands of cells for higher-level components. I know such wiring can be automated by a development tool, but it seems inefficient to have to process all those synapses. I think that making the COSA processor a little bit smarter and providing it with some knowledge about component boundaries could open up more possibilities for optimization.

Louis Savain said...

Josh McDonald,

LOL. Yep, after all these years, I am still a crackpot. And I love it.


It is important not to confuse the COSA processor with the COSA operating system. Only the latter knows about components. There are special system components dedicated to such tasks as memory management, I/O, creating, destroying, connecting cells and components, loading and saving components to mass storage, etc.

Special effectors like Start, Stop, Pause, Continue, Dup & Launch, etc. are (or should be, IMO) associated with invisible (to the programmer) system components that are dedicated to those tasks.

In my opinion, one of the nice things about COSA is that high-level components can be treated like low-level effectors. Indeed, the user interface of the programming environment should have the ability to depict them in the same way. It is a form of information hiding, i.e., a shorthanded way to present information to the user that is easily understood. I think it will do wonders for program comprehension.