Performance adjustment for Solid State Memory: Difference between revisions

From Try-AS/400
Jump to navigation Jump to search
New
 
 
(9 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{FIXME|Finish article}}
OS/400 '''Performance adjustment for Solid State Memory''' sheds some light on how to tune a system in regard to the almost zero latency for this type of secondary storage.
OS/400 '''Performance adjustment for Solid State Memory''' sheds some light on how to tune a system in regard to the almost zero latency for this type of secondary storage.


Line 8: Line 7:
Today, disks are largely replaced with solid state, '''[[wikipedia:Flash memory|flash based memory]]'''. It has no moving mechanical parts, eliminates the accompanying access latency, generates no noise, draws less power, generates less heat, and often uses less physical space. Older AS/400 systems can benefit from the [[ZuluSCSI]] parallel SCSI disk emulator.
Today, disks are largely replaced with solid state, '''[[wikipedia:Flash memory|flash based memory]]'''. It has no moving mechanical parts, eliminates the accompanying access latency, generates no noise, draws less power, generates less heat, and often uses less physical space. Older AS/400 systems can benefit from the [[ZuluSCSI]] parallel SCSI disk emulator.


OS/400 features a so called '''performance adjustment''' function, which automatically splits and shifts available memory around between memory pools according to the current workload, the goal is to minimize paging activtiy. The default threshold values when, and how much memory is moved around are based on the relatively high latency of rotating disk drives. One particular data point is the ''paging rate'', essentially how quickly the system tries to bring in data from secondary storage (disk) into primary storage (RAM) for processing. The higher the paging rate, the more aggressive memory is moved between pools.
OS/400 features a so called '''performance adjustment''' function, which automatically splits and shifts available memory around between memory pools according to the current workload, the goal is to minimize paging activity. The default threshold values when, and how much memory is moved around are based on the relatively high latency of rotating disk drives. One particular data point is the ''faulting rate'', essentially how quickly the system tries to bring in data from secondary storage (disk) into primary storage (RAM) for processing. The higher the faulting rate, the more aggressive memory is moved between pools.


Solid state memory allows very high paging rates, impossible with spinning disk drives, but without introducing excessive latency. The performance adjust doesn't base adjustment calculations on latency, but on paging rate. On a system with much disk activity, this can lead to memory starvation of less active pools, and frequent invalidation of in-memory cached data due to quick reassignments of memory.
<blockquote>'''Note:''' Despite the word ''fault'' seemingly indicating a fatal condition, it isn't. A [[wikipedia:Page fault|page fault]] is a mere indicator that a requested memory location isn't in main storage and a different code path has to be taken to bring it into main storage before processing can commence. Also, a single page fault can result in multiple memory pages being copied into main storage at once.</blockquote>
 
Solid state memory allows very high paging rates, impossible with spinning disk drives, but without introducing excessive latency. The performance adjust doesn't base adjustment calculations on latency, but on faulting rate. On a system with much disk activity, this can lead to memory starvation of less active pools, and frequent invalidation of in-memory cached data due to quick reassignments of memory.


== Work with Shared Pools ==
== Work with Shared Pools ==
The <code>wrkshrpool</code> command allows to adjust threshold values for the performance adjuster by pressing <code>F11</code>. You'll be presented with a table akin to the following. Suggested adjustment values are shown below. Values printed in ''bold'' are changed (non-default) values.
The <code>wrkshrpool</code> command allows to adjust threshold values for the performance adjuster by pressing <code>F11</code>. You'll be presented with a table akin to the following. This table shows default values (for V4R5):
{|class="wikitable"
!colspan="2"|&nbsp;
!colspan="2"|Size (%)
!colspan="3"|Faults/Second
|-
!Pool
!Priority
!Minimum
!Maximum
!Minimum
!Thread
!Maximum
|-
|*MACHINE
|align="right"|1
|align="right"|~25<ref>This value is actually calculated by the system.</ref>
|align="right"|100
|align="right"|10
|align="right"|0
|align="right"|10
|-
|*BASE
|align="right"|1
|align="right"|4.99
|align="right"|100
|align="right"|5
|align="right"|0.5
|align="right"|2000
|-
|*INTERACT
|align="right"|2
|align="right"|5
|align="right"|100
|align="right"|10
|align="right"|2
|align="right"|100
|-
|*SPOOL
|align="right"|2
|align="right"|1
|align="right"|100
|align="right"|5
|align="right"|1
|align="right"|100
|}
 
A pool's ''priority'' is a relative number from 1 to 14. Lower numbers mean higher priority for pools to be served with additional memory, while higher numbered pools are stripped from excess memory earlier.
 
Some explanation to the meaning of the ''Faults/Second'' values:
* '''Minimum''': If a pool's faulting rate drops below this value, the adjuster views the pool as over-allocated and will begin to strip memory away from it to feed other pools.
* '''Thread''': A multiplier per (active) thread.
* '''Maximum''': If the pool's faulting rate exceeds this value, the adjuster considers the pool starved and starts aggressively moving memory into it from other pools.
 
=== Thread multiplier ===
Explanation by example: If one user is running an application in the *INTERACT pool and causing 50 faults/second, that single user is experiencing a performance bottleneck. Contrary, if 100 people are using *INTERACT simultaneously and causing the same 50 faults/second, that means each user is only experiencing 0.5 faults/second. No bottleneck.
 
The system calculates a ''Dynamic Acceptable Fault Target Threshold = Minimum + (Thread Multiplier × Active Threads)''. If that value exceeds the absolute Maximum value, the latter is considered. Let's take an example of ''multiplier = 2''.
 
* Scenario A: The system is quiet (5 active threads)<br>
50 + (2 × 5) = 60 faults/s<br>
Because only 5 threads are active, the baseline is 60 faults/s. If overall pool activity exceeds 60 faults/s, adjustment will kick in.
* Scenario B: Peak hours (200 active threads)<br>
50 + (2 × 200) = 450 faults/s<br>
Now 200 threads are actively sharing the pool, and adjustment scales its tolerance up to 450 faults/sec before it considers the pool "starved" enough to warrant moving memory from elsewhere.
* Scenario C: Extreme burst (600 active threads)<br>
50 + (2 × 600) = 1250 faults/s<br>
Because the absolute Maximum is capped at 1000, the math is clipped. The threshold stops scaling and locks firmly at 1000 faults/s.
 
=== Recommended adjustments ===
Values printed in ''bold'' are changed (non-default) values.
 
<blockquote>'''Note:''' These values are intended for small scale, or hobbyist systems. If these values hold up for heavy usage has not been established. Expect these values to change over time when additional experience has been gained.</blockquote>


{|class="wikitable"
{|class="wikitable"
Line 30: Line 103:
|*MACHINE
|*MACHINE
|align="right"|1
|align="right"|1
|align="right"|25.49<ref>Use literal <tt>*DFT</tt> to reset to default, if unsure.</ref>
|align="right"|*DFT<ref>A literal <tt>*DFT</tt> isn't actually printed but can be used to reset to the default value if it has been changed prior.</ref>
|align="right"|'''50'''
|align="right"|'''50'''
|align="right"|'''100'''
|align="right"|'''100'''
Line 41: Line 114:
|align="right"|100
|align="right"|100
|align="right"|'''25'''
|align="right"|'''25'''
|align="right"|0.5
|align="right"|'''5'''
|align="right"|'''2000'''
|align="right"|'''2000'''
|-
|-
Line 49: Line 122:
|align="right"|'''25'''
|align="right"|'''25'''
|align="right"|'''50'''
|align="right"|'''50'''
|align="right"|2
|align="right"|'''10'''
|align="right"|'''1000'''
|align="right"|'''1000'''
|-
|-
Line 57: Line 130:
|align="right"|'''10'''
|align="right"|'''10'''
|align="right"|'''25'''
|align="right"|'''25'''
|align="right"|1
|align="right"|'''5'''
|align="right"|'''1000'''
|align="right"|'''1000'''
|}
|}


Some explanation to the meaning of the ''Faults/Second'' values:
The primary goals behind the suggested values are:
* '''Minimum''': If a pool's paging rate drops below this value, the adjuster views the pool as over-allocated and will begin to strip memory away from it to feed other pools.
* Establish hard ''Size %'' limits to prevent pool starvation.
* '''Thread''': The multiplier allocated per active thread. The OS calculates active threads by evaluating only threads that have actually consumed CPU slices during the most recent tuning interval.
* Allow for much higher faulting rates (''Faults/Second'') before taking action.
* '''Maximum''': If the pool's paging rate exceeds this value, the adjuster considers the pool starved and starts aggressively moving memory into it from other pools.
* Using higher scaling values still considers dynamic adjustment up to the raised ''Acceptable Fault Target Threshold'' values, and keeps the basic adjustment logic active.
 
The primary goals behind the suggested values are
* Establish hard ''Size %'' limits to prevent pool starvation
* Allow for much higher paging rates (''Faults/Second'') before taking action


== See also ==
== See also ==

Latest revision as of 10:51, 6 October 2026

OS/400 Performance adjustment for Solid State Memory sheds some light on how to tune a system in regard to the almost zero latency for this type of secondary storage.

OS/400 is an paged virtual memory platform. There's no direct open a file and read the content into RAM system function. All data between secondary and primary storage (historically disk, and RAM) flows through the paging code.

Today, disks are largely replaced with solid state, flash based memory. It has no moving mechanical parts, eliminates the accompanying access latency, generates no noise, draws less power, generates less heat, and often uses less physical space. Older AS/400 systems can benefit from the ZuluSCSI parallel SCSI disk emulator.

OS/400 features a so called performance adjustment function, which automatically splits and shifts available memory around between memory pools according to the current workload, the goal is to minimize paging activity. The default threshold values when, and how much memory is moved around are based on the relatively high latency of rotating disk drives. One particular data point is the faulting rate, essentially how quickly the system tries to bring in data from secondary storage (disk) into primary storage (RAM) for processing. The higher the faulting rate, the more aggressive memory is moved between pools.

Note: Despite the word fault seemingly indicating a fatal condition, it isn't. A page fault is a mere indicator that a requested memory location isn't in main storage and a different code path has to be taken to bring it into main storage before processing can commence. Also, a single page fault can result in multiple memory pages being copied into main storage at once.

Solid state memory allows very high paging rates, impossible with spinning disk drives, but without introducing excessive latency. The performance adjust doesn't base adjustment calculations on latency, but on faulting rate. On a system with much disk activity, this can lead to memory starvation of less active pools, and frequent invalidation of in-memory cached data due to quick reassignments of memory.

Work with Shared Pools

The wrkshrpool command allows to adjust threshold values for the performance adjuster by pressing F11. You'll be presented with a table akin to the following. This table shows default values (for V4R5):

  Size (%) Faults/Second
Pool Priority Minimum Maximum Minimum Thread Maximum
*MACHINE 1 ~25[1] 100 10 0 10
*BASE 1 4.99 100 5 0.5 2000
*INTERACT 2 5 100 10 2 100
*SPOOL 2 1 100 5 1 100

A pool's priority is a relative number from 1 to 14. Lower numbers mean higher priority for pools to be served with additional memory, while higher numbered pools are stripped from excess memory earlier.

Some explanation to the meaning of the Faults/Second values:

  • Minimum: If a pool's faulting rate drops below this value, the adjuster views the pool as over-allocated and will begin to strip memory away from it to feed other pools.
  • Thread: A multiplier per (active) thread.
  • Maximum: If the pool's faulting rate exceeds this value, the adjuster considers the pool starved and starts aggressively moving memory into it from other pools.

Thread multiplier

Explanation by example: If one user is running an application in the *INTERACT pool and causing 50 faults/second, that single user is experiencing a performance bottleneck. Contrary, if 100 people are using *INTERACT simultaneously and causing the same 50 faults/second, that means each user is only experiencing 0.5 faults/second. No bottleneck.

The system calculates a Dynamic Acceptable Fault Target Threshold = Minimum + (Thread Multiplier × Active Threads). If that value exceeds the absolute Maximum value, the latter is considered. Let's take an example of multiplier = 2.

  • Scenario A: The system is quiet (5 active threads)

50 + (2 × 5) = 60 faults/s
Because only 5 threads are active, the baseline is 60 faults/s. If overall pool activity exceeds 60 faults/s, adjustment will kick in.

  • Scenario B: Peak hours (200 active threads)

50 + (2 × 200) = 450 faults/s
Now 200 threads are actively sharing the pool, and adjustment scales its tolerance up to 450 faults/sec before it considers the pool "starved" enough to warrant moving memory from elsewhere.

  • Scenario C: Extreme burst (600 active threads)

50 + (2 × 600) = 1250 faults/s
Because the absolute Maximum is capped at 1000, the math is clipped. The threshold stops scaling and locks firmly at 1000 faults/s.

Recommended adjustments

Values printed in bold are changed (non-default) values.

Note: These values are intended for small scale, or hobbyist systems. If these values hold up for heavy usage has not been established. Expect these values to change over time when additional experience has been gained.

  Size (%) Faults/Second
Pool Priority Minimum Maximum Minimum Thread Maximum
*MACHINE 1 *DFT[2] 50 100 0 100
*BASE 1 4.99 100 25 5 2000
*INTERACT 2 5 25 50 10 1000
*SPOOL 3 1 10 25 5 1000

The primary goals behind the suggested values are:

  • Establish hard Size % limits to prevent pool starvation.
  • Allow for much higher faulting rates (Faults/Second) before taking action.
  • Using higher scaling values still considers dynamic adjustment up to the raised Acceptable Fault Target Threshold values, and keeps the basic adjustment logic active.

See also

Footnotes

  1. ↑ This value is actually calculated by the system.
  2. ↑ A literal *DFT isn't actually printed but can be used to reset to the default value if it has been changed prior.