Thursday, May 23, 2013

Shared memory, ISM and DISM

This topic is somewhat mysterious at first glance.
Furthermore, it seems lacking sufficient documentation.
After a quite long time frustrated with this I finally decided to discover the truth.
As always, this kind of things require us stepping into developer's land.
I believe that a good system administration implies a development.

Shared memory is an efficient way of passing data between processes.
That's part of a broader topic: Interprocess Communication (IPC).

In Unix world there are many standards and versions.
For example, there's the Single Unix Specification.
For this post, please, consider just the following:
  
  • <sys/ipc.h>
    <sys/shm.h>
       
  • ::shmget() - reserves shared memory.
    ::shmat()  - attaches to shared memory.
    ::shmdt()  - detaches from shared memory.
    ::shmctl() - free shared memory resources.
  
ISM and DISM are Solaris specific shared memory optimizations:

  • Intimate Shared Memory (ISM).
    This kind of shared memory is automatically locked by kernel upon segment creation. The locking prevents paging out and a fast I/O locking within the segment, saving significant CPU time. Furthermore, in contrast to "standard" shared memory, kernel V2P (virtual-to-physical) memory address translation structures are shared between processes, which saves kernel memory and also CPU time. In addition, large memory pages are automatically allocated for ISM segments, which reduces the number of memory pointers, thus reducing complexity and resulting in performance improvements, specially on large memory systems. Larger pages, less pointers and less shm-ids. As ISM is always locked, it isn't necessary to provide swap for back it up, which also saves disk space. To obtain an ISM segment, sufficient unlocked physical memory must be available. ISM segments are obtained by passing the SHM_SHARE_MMU flag to shmat(2).
      
  • Dynamic ISM (DISM).
    Builds on ISM but in contrast,  it's dynamically changeable. What isn't always clearly stated is that a DISM segment can't be shrunk. The "secret" is to obtain a large DISM segment right from the start. The size of the segment can be as large as the available virtual memory, hence disk swap is always involved. As such DISM reestablishes shared memory as pageable, although better optimized. DISM isn't automatically locked by the kernel. It's the responsibility of the application to lock, mlock(3C), and unlock, munlock(3C), segment pages, according to its own requirements, thus providing dynamic adjustment. DISM segments are obtained by passing the SHM_PAGEABLE flag to shmat(2).

In administering Solaris memory resources, beyond physical memory and virtual memory, depending on the application, it may be important to understand shared memory and locked memory. All these concepts are typically used by RDBMS such as Oracle Database, as an efficient interprocess communication mechanism, such as Oracle's SGA implementation.

For system administrators the more important conclusions on ISM and DISM are:

  • ISM doesn't affect swap and requires available physical memory, whereas DISM to be useful, generally relies on swap (not on physical memory). If swapping isn't desired, force ISM in order to not waste disk space for backing shared memory.
      
  • ISM and DISM are more efficient than the "standard" shared memory, consisting on a specific Solaris advantage.
      
One final crucial note is that shared memory (of any kind) in latest Solaris 10 and Solaris 11 systems is controlled by the max-shm-memory resource control, which defaults to ¼ of the installed physical memory.

And for wrapping up this subject, here's a shared memory code sample 1.0 and a shared memory run sample 1.0 for a more concrete approach.

A few incomplete references:
  
  • Solaris Internals: Solaris 10 and OpenSolaris Kernel Architecture, Ed. 2.
    Richard McDougall and Jim Mauro
    Part II, section 4.4.
      
  • Advanced Programming in the UNIX Environment, Ed. 3.
    W. Richard Stevens and Stephen A. Rago.
    Sections 15.6 XSI IPC and 15.9 Shared Memory.
       
  • Many My Oracle Support (MOS) documents.
      
  • man pages such as shmget(2), shmop(2)and shmctl(2).