| United States-English |
|
|
|
![]() |
Parallel Programming Guide for HP-UX Systems > Chapter 7 Memory
classesMemory class assignments |
|
In Fortran, compiler directives are used to assign memory
classes to data items. In C and C++, memory classes are assigned
through the use of syntax extensions, which are defined in the header
file
On a single-node system, HP compilers provide mechanisms for statically assigning memory classes. This chapter discusses these memory class assignments. The form of the directives and pragmas associated with is
shown in Table 7-1 Form of memory class directives and variable declarations
where (for Fortran)
where (for C)
In C and C++, data objects that are assigned a memory class must have static storage duration. This means that if the object is declared within a function, it must have the storage class extern or static. If such an object is not given one of these storage classes, its storage class defaults to automatic and it is allocated on the stack. Stack-based objects cannot be assigned a memory class; attempting to do so results in a compile-time error. Data objects declared at file scope and assigned a memory class need not specify a storage class. All C and C++ code examples presented in this chapter assume that the following line appears above the code presented:
This header file maps user symbols to the implementation reserved space. If operator new is used, it is also assumed that the line below appears above the code:
If you assign a memory class to a C or C++ structure, all structure members must be of the same class. Once a data item is assigned a memory class, the class cannot be changed. Static memory class assignments are physically located with variable type declarations in the source. Static memory classes are typically used with data objects that are accessed with equal frequency by all threads. These include objects of the thread_private and node_private classes. Static assignments for all classes are explained in the subsections that follow. Because thread_private variables are replicated for every thread, static declarations make the most sense for them. Example 7-1 thread_private In Fortran, the thread_private memory class is assigned using the THREAD_PRIVATE compiler directive, as shown in the following example:
Each array declared here is 8000 bytes in size, and each scalar variable is 8 bytes, for a total of 24,016 bytes of data. The entire COMMON block BLK1 is placed in thread_private memory along with TPX and TPY. All memory space is replicated for each thread in hypernode-local physical memory. Example 7-2 thread_private The following C/C++ example demonstrates several ways to declare thread_private storage. The data objects declared here are not scoped analogously to those declared in the Fortran example:
The C/C++ double data type provides the same precision as Fortran’s REAL*8. The thread_private data declared here occupies the same amount of memory as that declared in the Fortran example. tpa is available to all functions lexically following it in the file. tpb is local to func and inaccessible to other functions. tpc, a, and b are declared at filescope in another file that is linked with this one. Assume a Fortran or C program containing the appropriate example is running on a 4-hypernode subcomplex with 16 processors per hypernode and the thread_private memory is allocated from node_private memory (see the mpa(1) man page). Each data item requires 16 virtual addresses, for a total of 384,256 bytes of virtual space. These virtual addresses map to 16 physical addresses per hypernode, or 64 total physical addresses per data item, requiring a total of 1,537,024 (64 x 24016) bytes of physical memory. Example 7-3 thread_private COMMON blocks in parallel subroutines Data local to a procedure that is called in parallel is effectively private because storage for it is allocated on the thread’s private stack. However, if the data is in a Fortran COMMON block (or if it appears in a DATA or SAVE statement), it is not stored on the stack. Parallel accesses to such nonprivate data must be synchronized if it is assigned a shared class. Additionally, if the parallel copies of the procedure do not need to share the data, it can be assigned a private class. Consider the following Fortran example:
In this example, COMMON block BLK1 is declared THREAD_PRIVATE, so every parallel instance of PARCOM gets its own copy of the arrays C and D. Because this code is already thread-parallel when the COMMON block is defined, no further parallelism is possible, and BLK1 is therefore suitable for use anywhere in PARCOM. The local variables TEMP1 and TEMP2 are allocated on the stack, so each thread effectively has private copies of them. Because the space for node_private variables is physically replicated, static declarations make the most sense for them. In Fortran, the node_private memory class is assigned using the NODE_PRIVATE compiler directive, as shown in the following example:
Again, the data requires 24,016 bytes. The contents of BLK1 are placed in node_private memory along with XNP and YNP. Space for each data item is replicated once per hypernode in hypernode-local physical memory. The same virtual address is used by each thread to access its hypernode’s copy of a data item. node_private variables and arrays can be initialized in Fortran DATA statements. node_private data objects in C and C++:
The node_private data declared here occupies the same amount of memory as that declared in the Fortran example. Scoping rules for this data are similar to those given for the thread_private C/C++ example. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||