![]() |
![]() HP OpenVMS Systemsask the wizard |
![]() |
The Question is: In a previous question (wiz_1661.html) the Wizard said >> On Alpha, failure to use the memory barrier operators (when >> necessary) to ensure consistent memory contents -- memory >> barriers are used to properly control the (expected) read >> and write reordering normally found on Alpha. The barrier >> will block execution until all pending memory operations >> have completed. Could you please explain Memory Barriers a little further 1 - What Are They ... User Mode and/or Elevated Mode ? 2 - When to use them 3 - How to use them, ie what function calls 4 - A code example, showing how code would NOT or probably NOT work, follwed by same code, with correct usage of memory barrier, so code will work. Thank You Fred Bloggs The Answer is : The OpenVMS Wizard would strongly encourage you to read the information on memory barriers present in the Alpha Architecture Handbook. You can order this document, or you can download it from a pointer in the OpenVMS FAQ. A memory barrier is an Alpha instruction, and this instruction can be used in any processor privilege mode and at any time. There are two general types of memory barrier, those that involve synchornizing completion of loads and stores to memory, and the IMB PALcode routine that must be used after modifications are made to the instruction stream. (The IMB PALcode call is logically equivilent to the execution of the REI instruction required on VAX systems after an instruction stream modification.) You must use memory barriers when you want to guarantee the ordering of completion of memory operations. The Alpha Architecture permits the processor to re-order loads and stores; thus memory may be read or written in a different order than that specified by the programmer. This reordering is done to improve system performance, but it can occasionally also introduce undesirable side effects. The memory barrier instructions (MB and WMB) permit the programmer to explicitly synchronize the continued execution of the application with the necessary completion of all memory load and store operations currently outstanding. Using other terminology, a memory barrier is a synchronization point for memory. For a general example of the need for memory barriers, assume the following -- be aware of the distinction made between processes and processors in this discussion. Assume you have a shared memory global section containing a data structure. This data structure is protected by a lock cell that is stored in the shared memory. A process must acquire ownership of the data structure by setting the lock cell to a non-zero value (say, to the Process Id of the accessor) when it plans to write or update the contents of the data structure. All other processes will be prevented from accessing the structure when it is found locked, and will spin or otherwise defer access waiting for the lock cell to be cleared. Once the process holding the lock completes the necessary writes or modifications, it then clears the value in the lock cell by writing a zero back to the lock cell location. The Alpha processor -- because it may re-order loads and stores -- may choose to reorder the operations and write the lock cell location before it performs the updates on the contents of the data structure. Because of this reordering, other processes on other processors will then see the lock cell become zero and then (one process can) acquire the lock and may then read the same structure field(s) before the first processor has written the updated data to the field(s), thereby acquiring erronous (stale) data. While the programmer wrote the data to memory in the appopriate order, the Alpha processor reordered the memory access(es). The mechanism used to control this involves the execution of a MB instruction after the update to the structure field and prior to releasing the lock, and inserting another MB after releasing the lock. This will guarantee the ordering of the writes, and will ensures that all processes will see the correct data. Memory barriers are also used to control how an Alpha processor aggregates memory writes -- an Alpha processor may cache a memory write for some relatively long interval, before actually completing the write to memory. Until the data is written to memory, it is not visible to other Alpha processors in the system. Most of the time, this behaviour is entirely benign -- it often improves performance by permitting a processor to aggregate multiple write operations into a single memory bus transaction, caching and then sending multiple write operations out to memory together. There are cases where a programmer wants a write visible immediately, and the MB and the WMB instruction can be used to accomplish this. PALcode calls will contain memory barriers when appropriate, but an OpenVMS programmer should not assume that any particular intervening PALcode or OpenVMS system service call will contain a memory barrier operation. If a memory barrier is required for a particular series of memory operations, explicitly include the memory barrier in the code. How you write code that uses memory barriers depends on the language. Using Compaq C for OpenVMS Alpha, you can use the __MB builtin and the asm() directive. Please see the Compaq C User's Guide for OpenVMS Systems for additional details, or the user's guide for your particular language. The OpenVMS Alpha Macro32 compiler provides various built-ins, including the EVAX_IMB built-in. Examples of using memory barriers are included in the Alpha Architecture Handbook, and additional information on memory barriers is also present in the OpenVMS manual set. Please see these documents for additional details. The OpenVMS Wizard will leave the question of how to reliably deal with bitlocks, and how to spin appropriately, for topic (6984).
|