📄 dsoverview.tex
字号:
MPI has a number of data structures, most of which are represented by an opaque handle in an MPI program. In the MPICH implementation of MPI, these handles are represented as integers; this makes implementation of the C/Fortran handle transfer calls (part of MPI-2) easy. MPID objects (again with the possible exception of \texttt{MPI_Request}s) are allocated by a common set of object allocation functions. These are \begin{verbatim} void *MPIU_Handle_obj_create( MPIU_Object_alloc_t *objmem ) void MPIU_Handle_obj_destroy( MPIU_Object_alloc_t *objmem, void *object )\end{verbatim} where \texttt{objmem} is a pointer to a memory allocation object that knows enough to allocate objects, including the size of the object and the location of preallocated memory, as well as the type of memory allocator. By providing the routines to allocate and free the memory, we make it easy to use the same interface to allocate both local and shared memory for objects (always using the same kind for each type of object). The names create/destroy were chosen because they are different from new/delete (C++ operations) and malloc/free. Any name choice will have some conflicts with other uses, of course.\subsection{Reference Counts} Many MPI objects have reference count semantics. The semantics of MPI require that many objects that have been freed by the user (e.g., with \texttt{MPI_Type_free} or \texttt{MPI_Comm_free}) remain valid until all pending references to that object (e.g., by an \texttt{MPI_Irecv}) are complete. There are several ways to implement this; MPICH uses \emph{reference counts} in the objects. To support the \texttt{MPI_THREAD_MULTIPLE} level of thread-safety, these reference counts must be accessed and updated atomically. A reference count for \emph{any} object can be incremented (atomically) with \texttt{MPID_Object_add_ref(objptr)} and decremented with \texttt{MPID_Object_release_ref(objptr,newval_ptr)}. These have been designed so that then can be implemented as inlined macros rather than function calls, even in the multithreaded case, and can use special processor instructions that guarantee atomicity to avoid thread locks. The decrement routine sets the value pointed at by \texttt{inuse_ptr} to 0 if the postdecrement value of the reference counter is zero, and to a non-zero value otherwise. If this value is zero, then the routine that decremented the reference count should free the object. This may be as simple as calling \texttt{MPIU_Handle_obj_destroy} (for simple objects with no other allocated storage) or may require calling a separate routine to destroy the object. Because MPI uses \texttt{MPI_xxx_free} to both decrement the reference count and free the object if the reference count is zero, we avoid the use of \texttt{free} in the MPID routines. The \texttt{inuse_ptr} approach is used rather than requiring the post-decrement value because, for reference-count semantics, all that is necessary is to know when the reference count reaches zero, and this can sometimes be implemented more cheaply that requiring the post-decrement value (e.g., on IA32, there is an instruction for this operation).\subsection{Question} Should we state that this is a macro so that we can use a register for the output value? That avoids a store. Alternately, have the macro return the value as if it was a function?\subsection{Structure Definitions} The structure definitions in this document define \emph{only} that part of a structure that may be used by code that is making use of the ADI. Thus, some structures, such as \texttt{MPID_Comm}, have many defined fields; these are used to support MPI routines such as \texttt{MPI_Comm_size} and \texttt{MPI_Comm_remote_group}. Other structures may have few or no defined members; these structures have no fields used outside of the ADI. In C++ terms, all members of these structures are \texttt{private}. One example of such a structure is \texttt{MPID_Stream}. For the initial implementation, we expect that the structure definitions will be designed for the multimethod device. However, all items that are specific to a particular device (including the multi-method device) will be placed at the end of the structure; the document will clearly identify the members that all implementations will provide. This simplifies much of the code in both the ADI and the implementation of the MPI routines because structure member can be directly accessed rather than using some macro or C++ style method interface.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -