Managing server space for objects: Difference between revisions
m (Created page with "The <var class="product">Model 204</var> VTBL table is particularly impacted by <var class="product">Janus SOAP ULI</var> objects. VTBL spa...") |
No edit summary |
||
(16 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
==Overview== | |||
The <var class="product">Model 204</var> VTBL table is particularly impacted by | The <var class="product">Model 204</var> VTBL table is particularly impacted by | ||
<var class="product"> | <var class="product">SOUL</var> objects. | ||
VTBL space is required to accommodate two generic datastructures: | VTBL space is required to accommodate two generic datastructures: | ||
object references and object instances. | object references and object instances. | ||
Line 9: | Line 10: | ||
in parameters and in user method definitions), though they also may include | in parameters and in user method definitions), though they also may include | ||
some internal "work" object variables. | some internal "work" object variables. | ||
Object references are more complicated than <var class="product"> | Object references are more complicated than <var class="product">SOUL</var> | ||
%variables, and they take a few times more space in VTBL. | %variables, and they take a few times more space in VTBL. | ||
<li>Object instances, which are completely run-time products, | <li>Object instances, which are completely run-time products, | ||
are created by a class's [[Object variables#Using New or other Constructors|constructor]] | are created by a class's [[Object variables#Using New or other Constructors|constructor]] | ||
Line 24: | Line 26: | ||
</ul> | </ul> | ||
<var class="product"> | <var class="product">SOUL</var> uses object swapping to handle cases where | ||
a request has more objects than the compiler has reserved VTBL/STBL space for. | a request has more objects than the compiler has reserved VTBL/STBL space for. | ||
Object swapping involves the managing of server-resident slots — | Object swapping involves the managing of server-resident slots — | ||
Line 35: | Line 37: | ||
once the code that uses those object classes is considered. | once the code that uses those object classes is considered. | ||
The subsections that follow discuss <var class="product"> | The subsections that follow discuss <var class="product">SOUL</var> object swapping, | ||
the compiler directives | the compiler directives | ||
that let you exchange object swaps for server table space, | that let you exchange object swaps for server table space, | ||
Line 45: | Line 47: | ||
<li>[[#Displaying object statistics|Displaying object statistics]] | <li>[[#Displaying object statistics|Displaying object statistics]] | ||
</ul> | </ul> | ||
==Swapping objects== | ==Swapping objects== | ||
<var class="product"> | <var class="product">SOUL</var> objects effectively live in VTBL (and STBL) ''and'' in CCATEMP. | ||
The compiler reserves VTBL/STBL space for only a few object instances | The compiler reserves VTBL/STBL space for only a few object instances | ||
for each class that is referenced in a request. | for each class that is referenced in a request. | ||
Line 60: | Line 63: | ||
[[Object variables#Discarding implicitly|implicitly]]. | [[Object variables#Discarding implicitly|implicitly]]. | ||
The <var class="product"> | The <var class="product">SOUL</var> swapping scheme trades performance (CPU) for server size economy. | ||
In general, as swapping increases, performance slips. | In general, as swapping increases, performance slips. | ||
Decreasing the server size (number of object spaces allocated) means more | Decreasing the server size (number of object spaces allocated) means more | ||
Line 80: | Line 83: | ||
Because there is no right number of objects | Because there is no right number of objects | ||
to allocate at compile time, the <var class="product"> | to allocate at compile time, the <var class="product">SOUL</var> compiler directives, discussed below, | ||
are provided to allow a programmer who is more | are provided to allow a programmer who is more | ||
aware of the likely performance requirements of a class to set the | aware of the likely performance requirements of a class to set the | ||
Line 91: | Line 94: | ||
The <var>MaxObjects</var>, <var>MinObjects</var>, | The <var>MaxObjects</var>, <var>MinObjects</var>, | ||
and <var>AddObjects</var> options of the <var>Sirius</var> compiler directive | and <var>AddObjects</var> options of the <var>Sirius</var> compiler directive | ||
adjust the number of <var class="product"> | adjust the number of <var class="product">SOUL</var> objects for which VTBL/STBL space is allocated at | ||
request compile time. | request compile time. | ||
By default, that is, with no object compiler directives specified, <var class="product"> | By default, that is, with no object compiler directives specified, <var class="product">SOUL</var> | ||
allocates space for at most three (usually two) objects per class per request. | allocates space for at most three (usually two) objects per class per request. | ||
This ensures that only a small amount of server table space is used for objects, | This ensures that only a small amount of server table space is used for objects, | ||
Line 104: | Line 107: | ||
For details about the calculation of the space allocated for an object, | For details about the calculation of the space allocated for an object, | ||
see the description of the components of the object statistics | see the description of the components of the object statistics | ||
in [[#Message format| | in [[#Message format|Message format]]. | ||
Contrast the default allocation behavior | Contrast the default allocation behavior | ||
Line 130: | Line 133: | ||
<tr><th><i>option</i> | <tr><th><i>option</i> | ||
</th><td>One of the following: | </th><td>One of the following: | ||
<table> | <table class="thJustBold"> | ||
<tr><th>MaxObjects </th> | <tr><th>MaxObjects </th> | ||
<td>Sets an upper limit on the number of ''class'' objects for which space is allocated in VTBL/STBL. <code>Sirius MaxObjects</code> is useful for restraining server table size, although in some circumstances it can allow a larger allocation than if it were not specified. (For a demonstration of this paradoxical behavior, see the request example in | <td>Sets an upper limit on the number of ''class'' objects for which space is allocated in VTBL/STBL. <code>Sirius MaxObjects</code> is useful for restraining server table size, although in some circumstances it can allow a larger allocation than if it were not specified. (For a demonstration of this paradoxical behavior, see the request example in [[#How the compiler options interact|How the compiler options interact]].) | ||
[[#How the compiler options interact| | |||
<p> | <p> | ||
The Sirius MaxObjects default ''number'' setting is not a constant: when no <var>MaxObjects</var> directive is specified, the upper limit for the object allocation is set to the effective <var>MinObjects</var> value. </p> | The Sirius MaxObjects default ''number'' setting is not a constant: when no <var>MaxObjects</var> directive is specified, the upper limit for the object allocation is set to the effective <var>MinObjects</var> value. </p> | ||
Line 139: | Line 141: | ||
A <var>MaxObjects</var> setting of 1 is ''currently'' ignored, and a setting of 0 is a compilation error. </p> | A <var>MaxObjects</var> setting of 1 is ''currently'' ignored, and a setting of 0 is a compilation error. </p> | ||
<p> | <p> | ||
If there is more than one <code>Sirius MaxObjects</code> specification for a class, the minimum of these is the effective <var>MaxObjects</var> value. If there is both a <code>Sirius MaxObjects</code> and a <code>Sirius MinObjects</code> specification for aclass, the compiler allocation is bounded by their values and depends on the request complexity | If there is more than one <code>Sirius MaxObjects</code> specification for a class, the minimum of these is the effective <var>MaxObjects</var> value. If there is both a <code>Sirius MaxObjects</code> and a <code>Sirius MinObjects</code> specification for aclass, the compiler allocation is bounded by their values and depends on the request complexity (see [[#How the compiler options interact|How the compiler options interact]]). </p> </td></tr> | ||
(see [[#How the compiler options interact| | |||
<tr><th>MinObjects </th> | <tr><th>MinObjects </th> | ||
Line 148: | Line 149: | ||
Its default ''number'' setting is 2 for non-system objects and for most system objects. For some system object and method combinations, the default is 3. A setting of 1 is ''currently'' ignored, and a setting of 0 is a compilation error. </p> | Its default ''number'' setting is 2 for non-system objects and for most system objects. For some system object and method combinations, the default is 3. A setting of 1 is ''currently'' ignored, and a setting of 0 is a compilation error. </p> | ||
<p> | <p> | ||
If there is more than one <code>Sirius MinObjects</code> specification for a class, the maximum of these is the effective <var>MinObjects</var> value. If there is both a <code>Sirius MinObjects</code> and a <code>Sirius MaxObjects</code> specification for aclass, the compiler allocation is bounded by their values and depends on the request complexity | If there is more than one <code>Sirius MinObjects</code> specification for a class, the maximum of these is the effective <var>MinObjects</var> value. If there is both a <code>Sirius MinObjects</code> and a <code>Sirius MaxObjects</code> specification for aclass, the compiler allocation is bounded by their values and depends on the request complexity (see [[#How the compiler options interact|How the compiler options interact]]). </p> </td></tr> | ||
(see [[#How the compiler options interact| | |||
<tr><th>AddObjects </th> | <tr><th>AddObjects </th> | ||
Line 182: | Line 182: | ||
<p> | <p> | ||
This sets an upper limit on the number of objects for which space is allocated in VTBL/STBL. | This sets an upper limit on the number of objects for which space is allocated in VTBL/STBL. | ||
However, the space-conservative behavior of the default <var class="product"> | However, the space-conservative behavior of the default <var class="product">SOUL</var> object space | ||
allocation makes <code>Sirius MaxObjects</code> of limited utility. | allocation makes <code>Sirius MaxObjects</code> of limited utility. | ||
It may be most useful in a large program that liberally employs | It may be most useful in a large program that liberally employs | ||
Line 198: | Line 198: | ||
may allocate — it allows but does not force a greater allocation | may allocate — it allows but does not force a greater allocation | ||
(as <code>Sirius MinObjects</code> does). | (as <code>Sirius MinObjects</code> does). | ||
<li>As shown in [[#A MinObjects example|the next section]], | <li>As shown in [[#A MinObjects example|the next section]], | ||
the <var>OBJSTAT</var> statistics report lets you compare object allocation and swapping | the <var>OBJSTAT</var> statistics report lets you compare object allocation and swapping | ||
Line 205: | Line 206: | ||
command output to indicate the effect on CPU performance of your adjustments. | command output to indicate the effect on CPU performance of your adjustments. | ||
</ul> | </ul> | ||
===A MinObjects example=== | ===A MinObjects example=== | ||
To see the effects of the compiler directives, | To see the effects of the compiler directives, | ||
Line 251: | Line 253: | ||
allocated as in this example would have broken the program because of | allocated as in this example would have broken the program because of | ||
insufficient VTBL space. | insufficient VTBL space. | ||
<li>The CPU savings were not dramatic: | <li>The CPU savings were not dramatic: | ||
<var class="product"> | <var class="product">SOUL</var> object swapping is quite efficient. | ||
The savings are likely to be proportional to the size of the objects | The savings are likely to be proportional to the size of the objects | ||
that no longer are being swapped. | that no longer are being swapped. | ||
<li>The settings of the compiler directives were determined after a few trials. | <li>The settings of the compiler directives were determined after a few trials. | ||
Such testing is necessary because the effect of the setting of a directive | Such testing is necessary because the effect of the setting of a directive | ||
Line 268: | Line 272: | ||
If multiple directives are specified in a program for a class, this section describes rules for calculating the actual | If multiple directives are specified in a program for a class, this section describes rules for calculating the actual | ||
number of object instance slots for which the compiler allocates VTBL/STBL space. | number of object instance slots for which the compiler allocates VTBL/STBL space. | ||
< | <p class="note">'''Note:''' | ||
Remember that the number of object instance slots for which the compiler | Remember that the number of object instance slots for which the compiler | ||
allocates space may not be optimal in terms of swapping reduction. | allocates space may not be optimal in terms of swapping reduction. | ||
It may not be an amount that eliminates swapping. Or it may be an amount that eliminates swapping, but is not | It may not be an amount that eliminates swapping. Or it may be an amount that eliminates swapping, but is not | ||
the lowest number of slots at which swapping is eliminated. | the lowest number of slots at which swapping is eliminated. </p> | ||
These are identifiers for the critical values taken into consideration in the rules that follow: | These are identifiers for the critical values taken into consideration in the rules that follow: | ||
<table> | <table class="thJustBold"> | ||
<tr><th>AbMin | <tr><th>AbMin | ||
</th><td>Per class, the required minimum number of object instances for which space must be allocated in any request. This value overrides any and all explicit directives: the compiler will in all circumstances allocate at least <code>AbMin</code> object slots. | </th><td>Per class, the required minimum number of object instances for which space must be allocated in any request. This value overrides any and all explicit directives: the compiler will in all circumstances allocate at least <code>AbMin</code> object slots. | ||
</td></tr> | </td></tr> | ||
<tr><th>Max | <tr><th>Max | ||
</th><td>The effective <var>MaxObjects</var> value. Per class, the lowest <var>Sirius MaxObjects</var> setting. | </th><td>The effective <var>MaxObjects</var> value. Per class, the lowest <var>Sirius MaxObjects</var> setting. | ||
</td></tr> | </td></tr> | ||
<tr><th>Add | <tr><th>Add | ||
</th><td>The effective <var>AddObjects</var> value. Per class, the sum of the <var>Sirius AddObjects</var> settings. | </th><td>The effective <var>AddObjects</var> value. Per class, the sum of the <var>Sirius AddObjects</var> settings. | ||
</td></tr> | </td></tr> | ||
<tr><th>Min | <tr><th>Min | ||
</th><td>The effective <var>MinObjects</var> value. Per class, the larger of these: <ul> <li><code>AbMin</code> <li>The highest <var>Sirius MinObjects</var> setting, plus <code>Add</code>. </ul> | </th><td>The effective <var>MinObjects</var> value. Per class, the larger of these: <ul> <li><code>AbMin</code> <li>The highest <var>Sirius MinObjects</var> setting, plus <code>Add</code>. </ul> | ||
</td></tr> | </td></tr> | ||
<tr><th>Native | <tr><th>Native | ||
</th><td>The object instance allocation count determined by the compiler before consideration of any explicit or implied directives. This count is typically very close to the number of object variable declarations in the program. | </th><td>The object instance allocation count determined by the compiler before consideration of any explicit or implied directives. This count is typically very close to the number of object variable declarations in the program. | ||
<p> | <p> | ||
In the program in [[#A MinObjects example| | In the program in [[#A MinObjects example|A MinObjects example]], the compiler would allocate space | ||
for 32 <code>LONG</code> class object instances if it were not for the default limit (<code>MinObjects=2</code>)or | for 32 <code>LONG</code> class object instances if it were not for the default limit (<code>MinObjects=2</code>)or | ||
for any explicit directives. However, with <var>MinObjects</var> set to 20, swapping was reduced to 0. | for any explicit directives. However, with <var>MinObjects</var> set to 20, swapping was reduced to 0. | ||
Line 330: | Line 338: | ||
<p> | <p> | ||
The request produces the default allocation for <var>Stringlists</var>: </p> | The request produces the default allocation for <var>Stringlists</var>: </p> | ||
<p class="code">OBJECT SYSTEM:STRINGLIST: objects/VTBL/STBL - 3/18/0, count/pages swapped 21/21 | <p class="code" style="font-size:80%">OBJECT SYSTEM:STRINGLIST: objects/VTBL/STBL - 3/18/0, <br> count/pages swapped 21/21 | ||
COLLECTION SYSTEM:ARRAYLIST OF OBJECT SYSTEM:STRINGLIST: objects/VTBL/STBL - 2/17/0, count/pages swapped 0/0 | COLLECTION SYSTEM:ARRAYLIST OF OBJECT SYSTEM:STRINGLIST: objects/VTBL/STBL - 2/17/0, <br> count/pages swapped 0/0 | ||
</p> | </p> | ||
With a <var>Sirius MaxObjects</var> setting that is sufficiently high (say, 25), | With a <var>Sirius MaxObjects</var> setting that is sufficiently high (say, 25), | ||
the compiler allocates object instance slots (6) according to its "Native" algorithm: | the compiler allocates object instance slots (6) according to its "Native" algorithm: | ||
<p class="code">OBJECT SYSTEM:STRINGLIST: objects/VTBL/STBL - 6/35/0, count/pages swapped 18/18 | <p class="code" style="font-size:80%">OBJECT SYSTEM:STRINGLIST: objects/VTBL/STBL - 6/35/0, count/pages swapped 18/18 | ||
COLLECTION SYSTEM:ARRAYLIST OF OBJECT SYSTEM:STRINGLIST: objects/VTBL/STBL - 2/17/0, count/pages swapped 0/0 | COLLECTION SYSTEM:ARRAYLIST OF OBJECT SYSTEM:STRINGLIST: objects/VTBL/STBL - 2/17/0, <br> count/pages swapped 0/0 | ||
</p> | </p> | ||
<p> | <p> | ||
Line 343: | Line 351: | ||
even if the objects declared are not instantiated. The example also shows how the <code>Native</code> | even if the objects declared are not instantiated. The example also shows how the <code>Native</code> | ||
count may not account for objects within collections. </p> | count may not account for objects within collections. </p> | ||
</td></tr></table> | </td></tr> | ||
</table> | |||
The following rules describe the compiler allocation outcomes when | The following rules describe the compiler allocation outcomes when | ||
Line 350: | Line 359: | ||
<li>The number of object slots allocated for a class | <li>The number of object slots allocated for a class | ||
is '''never''' allowed to fall below <code>AbMin</code> for that class. | is '''never''' allowed to fall below <code>AbMin</code> for that class. | ||
<li>The number of object slots allocated for a class is '''not''' | <li>The number of object slots allocated for a class is '''not''' | ||
allowed to exceed <code>Max</code> for that class. | allowed to exceed <code>Max</code> for that class. | ||
The only exception is if <code>Max</code> is less than <code>AbMin</code>. | The only exception is if <code>Max</code> is less than <code>AbMin</code>. | ||
<li>In the absence of any <var>MaxObjects</var> settings, <code>Min</code> becomes the | <li>In the absence of any <var>MaxObjects</var> settings, <code>Min</code> becomes the | ||
effective <code>Max</code>. | effective <code>Max</code>. | ||
<li>If there is a combination of <var>Sirius MaxObjects</var> and <var>Sirius MinObjects</var> specification for a class, the | <li>If there is a combination of <var>Sirius MaxObjects</var> and <var>Sirius MinObjects</var> specification for a class, the | ||
compiler allocates as follows: | compiler allocates as follows: | ||
<table> | <table> | ||
<tr><th>Situation | <tr class="head"><th>Situation | ||
</th><th>Object slots allocated | </th><th>Object slots allocated | ||
</th></tr> | </th></tr> | ||
Line 372: | Line 384: | ||
</ol> | </ol> | ||
</td></tr> | </td></tr> | ||
<tr><td>Max <= Min | <tr><td nowrap>Max <= Min</td> | ||
</td><td><b>Max</b> | <td><b>Max</b> | ||
<p> | <p> | ||
The compiler will try to allocate Min object slots, | The compiler will try to allocate Min object slots, | ||
but it will "stop" when it reaches Max (by rule 2, Max is not exceeded). </p> | but it will "stop" when it reaches Max (by rule 2, Max is not exceeded). </p></td></tr> | ||
</td></tr></table> | </table> | ||
</ol> | </ol> | ||
<p class="caption">Object allocation (multiple directives, Min < Max)</p> | <p class="caption" style="margin-right:2em">Object allocation (multiple directives, Min < Max) </p> | ||
<p class=" | <p class="figure">[[File:cfiggg3a.png|center|border|450px]] </p> | ||
<p> | <p> | ||
Cases <code>a</code>, <code>b</code>, and <code>c</code> in the figure above | Cases <code>a</code>, <code>b</code>, and <code>c</code> in the figure above | ||
Line 394: | Line 406: | ||
by including user method definitions only if the methods are actually called. | by including user method definitions only if the methods are actually called. | ||
<var class="product">SOUL</var> classes incorporate a "header file" type of design: | |||
the declaration of | the declaration of | ||
classes is distinct from the code that implements the classes. | classes is distinct from the code that implements the classes. | ||
Line 410: | Line 422: | ||
or method code within a single compilation of a complex program. | or method code within a single compilation of a complex program. | ||
You can even programmatically prevent such duplicate includes | You can even programmatically prevent such duplicate includes | ||
by using the <var>[[!DUPEXIT]]</var> <var class="product"> | by using the <var>[[!DUPEXIT]]</var> <var class="product">SOUL</var> macro. | ||
==Displaying object statistics== | ==Displaying object statistics== | ||
The <var>OBJSTAT</var> User 0 parameter controls the display of journal messages that contain user statistics about <var class="product"> | The <var>OBJSTAT</var> User 0 parameter controls the display of journal messages that contain user statistics about <var class="product">SOUL</var> object usage per request. The messages specify server table usage (VTBL and STBL) and object-swapping counts per object class and summed for all classes. | ||
===Message format=== | ===Message format=== | ||
You can set <var>OBJSTAT</var> to display object statistics after program compilation, evaluation, or both (as described below in [[#Setting OBJSTAT| | You can set <var>OBJSTAT</var> to display object statistics after program compilation, evaluation, or both (as described below in [[#Setting OBJSTAT|Setting OBJSTAT]]). The layout for post-compilation messages is the same as that for | ||
post-evaluation messages, as described below and as shown in [[#Sample object statistics| | post-evaluation messages, as described below and as shown in [[#Sample object statistics|Sample object statistics]]: | ||
<ul> | <ul> | ||
<li>One message for each class of objects instantiated in the program, with this format: | <li>One message for each class of objects instantiated in the program, with this format: | ||
<p class="code">MSIR.0884: [ OBJECT | COLLECTION ] <i>classname</i>: objects/VTBL/STBL - <i>obj</i>/<i>vtb</i>/<i>stb</i>, count/pages swapped <i>osw</i>/<i>psw</i> </p> | <p class="code">MSIR.0884: [OBJECT | COLLECTION] <i>classname</i>: objects/VTBL/STBL - <i>obj</i>/<i>vtb</i>/<i>stb</i>, count/pages swapped <i>osw</i>/<i>psw</i> </p> | ||
<li>A single message that reports the sum of the counts of the preceding individual classes, with this format: | <li>A single message that reports the sum of the counts of the preceding individual classes, with this format: | ||
<p class="code">MSIR.0884: *TOTAL*: objects/VTBL/STBL - <i>obj</i>/<i>vtb</i>/<i>stb</i>, count/pages swapped <i>osw</i>/<i>psw</i> </p> | <p class="code">MSIR.0884: *TOTAL*: objects/VTBL/STBL - <i>obj</i>/<i>vtb</i>/<i>stb</i>, count/pages swapped <i>osw</i>/<i>psw</i> </p> | ||
Line 426: | Line 438: | ||
Where: | Where: | ||
<table> | <table class="thJustBold"> | ||
<tr><th><i | <tr><th><i>classname</i></th> | ||
</th><td>Identifies the name of the class for which space for object instances is allocated. | <td>Identifies the name of the class for which space for object instances is allocated. System classes are prefixed with <code>SYSTEM:</code>. System enumerations are excluded because they are not stored in VTBL or STBL.</td></tr> | ||
because they are not stored in VTBL or STBL. | <tr><th>objects</th> | ||
</td></tr> | <td>Object instances for which server space is allocated for the indicated class (or for all classes) for the request. This space is allocated at compile time, thus separate from the actual number of run-time objects used. | ||
<tr><th>objects | |||
</th><td>Object instances for which server space is allocated for the indicated class (or for all classes) for the request. This space is allocated at compile time, thus separate from the actual number of run-time objects used. | |||
<p> | <p> | ||
The number of <code>objects</code> allocated is <i><code>obj</code></i></p> | The number of <code>objects</code> allocated is <i><code>obj</code></i></p> | ||
</td></tr> | </td></tr> | ||
<tr><th>VTBL | |||
</th><td>VTBL units (32 bytes per unit) occupied by the <code>objects</code>. Each instance of an object in a given class requires the same amount of space: a fixed amount for an object header, and a non-fixed amount for each member variable (that is, every variable in the <var>Public</var> or <var>Private</var> — but not <var>Public Shared</var> or <var>Private Shared</var> — blocks). | <tr><th>VTBL</th> | ||
<td>VTBL units (32 bytes per unit) occupied by the <code>objects</code>. Each instance of an object in a given class requires the same amount of space: a fixed amount for an object header, and a non-fixed amount for each member variable (that is, every variable in the <var>Public</var> or <var>Private</var> — but not <var>Public Shared</var> or <var>Private Shared</var> — blocks). | |||
<p> | <p> | ||
The number of VTBL units allocated is <i><code>vtb</code></i>. </p> | The number of VTBL units allocated is <i><code>vtb</code></i>. </p> | ||
<p> | <p> | ||
The <i><code>vtb</code></i> units do '''not''' include the VTBL space that is occupied by each local object reference in the main program routine. These references include object variables in declarations (including method parameter declarations and explicit and implicit method objects) and "work" object variables. These work variables are used to hold intermediate results in the evaluation of statements containing method concatenations. They may be reused within the class, and they typically do not add significantly to the VTBL space used. Object references use 2 VTBL units each, excepting <var>XmlNodes</var>, which use approximately 8. </p> | The <i><code>vtb</code></i> units do '''not''' include the VTBL space that is occupied by each local object reference in the main program routine. These references include object variables in declarations (including method parameter declarations and explicit and implicit method objects) and "work" object variables. These work variables are used to hold intermediate results in the evaluation of statements containing method concatenations. They may be reused within the class, and they typically do not add significantly to the VTBL space used. Object references use 2 VTBL units each, excepting <var>XmlNodes</var>, which use approximately 8. </p></td></tr> | ||
</td></tr> | |||
<tr><th>STBL | <tr><th>STBL</th> | ||
</th><td>STBL bytes occupied by the <var>objects</var>. Parts of some objects, such as string and longstring variable values, use STBL. | <td>STBL bytes occupied by the <var>objects</var>. Parts of some objects, such as string and longstring variable values, use STBL. | ||
<p> | <p> | ||
The number of STBL units allocated is <i><code>stb</code></i>. </p> | The number of STBL units allocated is <i><code>stb</code></i>. </p> | ||
</td></tr> | </td></tr> | ||
<tr><th nowrap="true"><i | |||
</th><td>The number, respectively, of <code>objects</code>, <code>VTBL</code> units, and <code>STBL</code> bytes. < | <tr><th nowrap="true"><i>obj</i>, <i>vtb</i>, <i>stb</i></th> | ||
</td></tr> | <td>The number, respectively, of <code>objects</code>, <code>VTBL</code> units, and <code>STBL</code> bytes. | ||
<tr><th>count | <p class="note">'''Note:''' These amounts encompass all the space used for object instances, which includes some internal overhead. It does '''not''' include the space used for object ''references'', that is, object variables. </p></td></tr> | ||
</th><td>The count of object swaps: the number of times object instances of this class were swapped into or out of the server during the request. | |||
<tr><th>count</th> | |||
<td>The count of object swaps: the number of times object instances of this class were swapped into or out of the server during the request. | |||
<p> | <p> | ||
The value of <code>count</code> is <i><code>osw</code></i>. | The value of <code>count</code> is <i><code>osw</code></i>. </p> | ||
< | <p class="note">'''Note:''' A swap out counts as one, and a swap in as one, so a swap in and out counts as two. Accessing a global/session object counts as a swap in, since objects do not sit in the server between requests, so they need to be swapped into/out of CCATEMP. Swaps happen only during evaluation, so this number should always be zero in the post-compilation statistics. </p></td></tr> | ||
</td></tr> | |||
<tr><th nowrap="true">pages swapped | <tr><th nowrap="true">pages swapped</th> | ||
</th><td>The number of 6144-byte pages swapped into or out of the server. This number should always be an integral multiple of <code>count</code>, and the multiplier should be one, except for very large objects (greater than 6144 bytes). | <td>The number of 6144-byte pages swapped into or out of the server. This number should always be an integral multiple of <code>count</code>, and the multiplier should be one, except for very large objects (greater than 6144 bytes). | ||
<p> | <p> | ||
The value of <code>pages swapped</code> is <i><code>psw</code></i>. </p> | The value of <code>pages swapped</code> is <i><code>psw</code></i>. </p> | ||
</td></tr> | </td></tr> | ||
<tr><th><i | |||
</th><td>Values, respectively, of <code>count</code> and <code>pages</code> <code>swapped</code>. | <tr><th><i>osw</i>, <i>psw</i></th> | ||
</td></tr> | <td>Values, respectively, of <code>count</code> and <code>pages</code> <code>swapped</code>.</td></tr> | ||
</table> | </table> | ||
Line 473: | Line 486: | ||
It contains the following bit options, two or more of which you | It contains the following bit options, two or more of which you | ||
can select by specifying the sum of their bit values: | can select by specifying the sum of their bit values: | ||
<table> | <table class="thJustBold"> | ||
<tr><th>X'00' | <tr><th>X'00' | ||
</th><td>Display no <var>OBJSTAT</var> statistics; this is the default. | </th><td>Display no <var>OBJSTAT</var> statistics; this is the default. | ||
</td></tr> | </td></tr> | ||
<tr><th>X'01' | <tr><th>X'01' | ||
</th><td>Display post-compilation object statistics to the journal. | </th><td>Display post-compilation object statistics to the journal. | ||
</td></tr> | </td></tr> | ||
<tr><th>X'02' | <tr><th>X'02' | ||
</th><td>Display post-evaluation object statistics to the journal. | </th><td>Display post-evaluation object statistics to the journal. | ||
</td></tr> | </td></tr> | ||
<tr><th>X'10' | <tr><th>X'10' | ||
</th><td>Display post-compilation object statistics to both the terminal and the journal. | </th><td>Display post-compilation object statistics to both the terminal and the journal. | ||
</td></tr> | </td></tr> | ||
<tr><th>X'20' | <tr><th>X'20' | ||
</th><td>Display post-evaluation object statistics to both the terminal and the journal. | </th><td>Display post-evaluation object statistics to both the terminal and the journal.</td></tr> | ||
</td></tr> | |||
</table> | </table> | ||
'''Note:''' | |||
X'22' is the same as X'20'; X'10' is the same as X'11'; and X'30' is the same as | <p class="note">'''Note:''' | ||
X'31', X'32', or X'33'. | X'22' is the same as X'20'; X'10' is the same as X'11'; and X'30' is the same as X'31', X'32', or X'33'. </p> | ||
You can set <var>OBJSTAT</var> in the User 0 stream, and you can reset it | You can set <var>OBJSTAT</var> in the User 0 stream, and you can reset it | ||
Line 521: | Line 537: | ||
For a case where these statistics guide the | For a case where these statistics guide the | ||
tuning of the object allocation algorithm, see [[#A MinObjects example| | tuning of the object allocation algorithm, see [[#A MinObjects example|A MinObjects example]]. | ||
==See also== | |||
<ul> | |||
<li>[[Classes and Objects]] | |||
<li>[[Object variables]] | |||
<li>[[Copying objects]] | |||
<li>[[Global and session objects]] | |||
<li>[[Object oriented programming in SOUL]] | |||
</ul> | |||
[[Category:Overviews]] | |||
[[Category:SOUL object-oriented programming topics]] |
Latest revision as of 17:24, 25 May 2017
Overview
The Model 204 VTBL table is particularly impacted by SOUL objects. VTBL space is required to accommodate two generic datastructures: object references and object instances.
- Object references, each of which in a program is allocated a fixed amount of VTBL space at compile time, are primarily object variable declarations (explicit and implicit, in parameters and in user method definitions), though they also may include some internal "work" object variables. Object references are more complicated than SOUL %variables, and they take a few times more space in VTBL.
- Object instances, which are completely run-time products, are created by a class's constructor methods (called explicitly or implicitly). The compiler reserves VTBL space to store the object instances in anticipation of their creation. For any object of any class ever referenced within a request, there must be space for at least one instance of the object in VTBL (and STBL, for parts of some objects, such as string variables). For certain methods, two, and rarely, three, instances must be available in VTBL at once.
SOUL uses object swapping to handle cases where a request has more objects than the compiler has reserved VTBL/STBL space for. Object swapping involves the managing of server-resident slots — object-instance "containers" — and the swapping of object instances between those slots in the server and pages of CCATEMP. This scheme combines extremely efficient access to object data with a modest memory requirement, and it may even produce smaller server sizes than comparable non-object applications once the code that uses those object classes is considered.
The subsections that follow discuss SOUL object swapping, the compiler directives that let you exchange object swaps for server table space, and statistics that report both swapping and server space allocation:
- Swapping objects
- Using compiler directives to modify object allocation
- Selectively compiling user methods
- Displaying object statistics
Swapping objects
SOUL objects effectively live in VTBL (and STBL) and in CCATEMP. The compiler reserves VTBL/STBL space for only a few object instances for each class that is referenced in a request. At run time, these object-instance slots are used for the objects instantiated in the request. If the number of objects instantiated exceeds the compiler-allocated slots, the swapping of objects out to CCATEMP begins.
The least-recently-used objects get swapped out. If such an object is referenced again, it gets swapped back in, probably pushing another object out. No server or CCATEMP space is kept for objects discarded explicitly or implicitly.
The SOUL swapping scheme trades performance (CPU) for server size economy. In general, as swapping increases, performance slips. Decreasing the server size (number of object spaces allocated) means more swapping is necessary. Increasing the number of object slots means less swapping but a larger server size.
Unfortunately, although object references are easily tracked during compilation, it is impossible to determine the right number of object instance slots to reserve in all but the simplest programs. Guessing the size of the "normal" working set of object instances of a particular class requires knowledge of what the program is doing and what its inputs are expected to be. Using the count of object references is not sufficient: In one program, all object references may point to a single collection object, for example, whereas in another program, each object variable may reference a different object.
Because there is no right number of objects to allocate at compile time, the SOUL compiler directives, discussed below, are provided to allow a programmer who is more aware of the likely performance requirements of a class to set the correct number of objects programmatically. In most cases these directives will not be necessary: most simple object-oriented applications have few objects, so swapping will be minimal. And even in complex applications where swapping is greater, the directives should be a recourse only if performance degrades intolerably.
Using compiler directives to modify object allocation
The MaxObjects, MinObjects, and AddObjects options of the Sirius compiler directive adjust the number of SOUL objects for which VTBL/STBL space is allocated at request compile time.
By default, that is, with no object compiler directives specified, SOUL allocates space for at most three (usually two) objects per class per request. This ensures that only a small amount of server table space is used for objects, and no object swapping occurs until more than two or three objects in a class are instantiated at the same time. This approach also prevents an exceptional, object-heavy request from forcing server tables to be huge for all requests.
For details about the calculation of the space allocated for an object, see the description of the components of the object statistics in Message format.
Contrast the default allocation behavior with a scheme designed to maximize performance, in which one object is allocated for every object reference in the request. This high-allocation approach eliminates most object swapping, but it is likely to allocate considerably more server space than is necessary for most programs. An extreme example of this is an application that has dozens of object variables, especially object variable parameters, that all reference the same object. In this case, VTBL/STBL space would be allocated for dozens of objects, yet most of the space would be unused.
You can adjust the allocation behavior by specifying one or more Sirius compiler directives in your program. You locate the directive after the Begin statement; directives referencing a user-defined class must follow the class definition. The directives have the following format:
Sirius option class number
Where:
option | One of the following:
| ||||||
---|---|---|---|---|---|---|---|
class | The name of the system or user class for which you are specifying a directive.
For a collection, instead of a name, you specify the type of collection (for example, | ||||||
number | The number of object instances of class class for which to allocate space. |
Usage notes:
- Typically, you use these directive options to trade server space
for performance gain, depending on the constraints in effect at your site
and the type of requests you are running.
Your most likely options are:
- To emphasize performance, increase the
Sirius MinObjects
setting for one or more classes.This increases the number of object instances for which space is allocated in VTBL/STBL. The result is less swapping between the server table and CCATEMP, so better CPU performance. The expense is VTBL/STBL resources, so you may need to increase your VTBL or STBL size.
- To restrain server size, specify a
Sirius MaxObjects
setting for one or more classes.This sets an upper limit on the number of objects for which space is allocated in VTBL/STBL. However, the space-conservative behavior of the default SOUL object space allocation makes
Sirius MaxObjects
of limited utility. It may be most useful in a large program that liberally employs MinObjects and AddObjects directives. A singleSirius MaxObjects
directive at the top of the program can act as an overall safeguard on the required server table space.For some programs that make extensive use of user classes, selectively including object methods is an approach that may provide a significant reduction in server requirements. This is described in "Selectively compiling user methods".
- To emphasize performance, increase the
Sirius MaxObjects
only raises the ceiling for the number of object instance slots that the compiler may allocate — it allows but does not force a greater allocation (asSirius MinObjects
does).- As shown in the next section, the OBJSTAT statistics report lets you compare object allocation and swapping to help you determine whether and how much to adjust the object allocation of any of the classes in your program. You can also use Model 204 TIME REQUEST command output to indicate the effect on CPU performance of your adjustments.
A MinObjects example
To see the effects of the compiler directives,
consider the object allocation report shown in "Sample object statistics".
Those statistics (invoked by the OBJSTAT parameter)
show object handling when no compiler directives are specified.
Note the relatively high swapping counts of the LONG
, PT
, and CELL
objects:
OBJECT LONG: objects/VTBL/STBL - 2/7/0, count/pages swapped 571/571 OBJECT PT: objects/VTBL/STBL - 2/18/0, count/pages swapped 310/310 OBJECT CELL: objects/VTBL/STBL - 2/20/0, count/pages swapped 528/528 ... *TOTAL*: objects/VTBL/STBL - 14/163/144, count/pages swapped 1409/1409
The output from a T REQUEST command issued in that situation includes the following statistics:
STBL=8453 VTBL=1002 CPU=1064 OBJSWAP=1409
In an effort to maximize performance in this case, the following compiler directives are set to allocate space for more of these object instances in VTBL (they are not using STBL), thereby reducing swapping:
Sirius Minobjects Long 20 Sirius Minobjects Pt 15 Sirius Minobjects Cell 310
After rerunning the program, the resulting OBJSTAT statistics show the swapping eliminated (at the expense of additional VTBL space):
OBJECT LONG: objects/VTBL/STBL - 20/63/0, count/pages swapped 0/0 OBJECT PT: objects/VTBL/STBL - 15/132/0, count/pages swapped 0/0 OBJECT CELL: objects/VTBL/STBL - 310/3023/0, count/pages swapped 0/0 ... *TOTAL*: objects/VTBL/STBL - 353/3336/144, count/pages swapped 0/0
The T REQUEST output shows reduced CPU, increased VTBL consumption,
and no OBJSWAP
value (indicating that there was no swapping):
STBL=8453 VTBL=4174 CPU=1053
Comments:
- Without a suitably large VTBL, increasing the number of object instances allocated as in this example would have broken the program because of insufficient VTBL space.
- The CPU savings were not dramatic: SOUL object swapping is quite efficient. The savings are likely to be proportional to the size of the objects that no longer are being swapped.
- The settings of the compiler directives were determined after a few trials. Such testing is necessary because the effect of the setting of a directive is program and object dependent. In this case, the directives for two of the objects did not have to be set very large to prevent swapping, whereas the third object required a relatively large value. In the program, this third object was often instantiated as a collection item, so it was relatively under-counted by the object allocation algorithm, which relies heavily on a count of explicit object declarations.
How the compiler options interact
If multiple directives are specified in a program for a class, this section describes rules for calculating the actual number of object instance slots for which the compiler allocates VTBL/STBL space.
Note: Remember that the number of object instance slots for which the compiler allocates space may not be optimal in terms of swapping reduction. It may not be an amount that eliminates swapping. Or it may be an amount that eliminates swapping, but is not the lowest number of slots at which swapping is eliminated.
These are identifiers for the critical values taken into consideration in the rules that follow:
AbMin | Per class, the required minimum number of object instances for which space must be allocated in any request. This value overrides any and all explicit directives: the compiler will in all circumstances allocate at least AbMin object slots.
|
---|---|
Max | The effective MaxObjects value. Per class, the lowest Sirius MaxObjects setting. |
Add | The effective AddObjects value. Per class, the sum of the Sirius AddObjects settings. |
Min | The effective MinObjects value. Per class, the larger of these:
|
Native | The object instance allocation count determined by the compiler before consideration of any explicit or implied directives. This count is typically very close to the number of object variable declarations in the program.
In the program in A MinObjects example, the compiler would allocate space
for 32
To determine the For another example, consider the following request, which declares multiple objects that are never instantiated: Begin %sla Collection Arraylist Of Object Stringlist Auto New %sl Object Stringlist %slnew Object Stringlist %slnew2 Object Stringlist %slnew3 Object Stringlist %slnew4 Object Stringlist %i Float %j Float %limit Float %limit = 8 For %i From 1 To %limit %sl = New For %j From 1 To %i %sl:Add('Strlist ' With %i With ' item ' With %j) End For %sla:Add(%sl) End For For %i From 1 To %limit Print '--- Item ' %i ' has ' %sla(%i):Count ' items' %sla(%i):Print End For End The request produces the default allocation for Stringlists: OBJECT SYSTEM:STRINGLIST: objects/VTBL/STBL - 3/18/0, With a Sirius MaxObjects setting that is sufficiently high (say, 25), the compiler allocates object instance slots (6) according to its "Native" algorithm: OBJECT SYSTEM:STRINGLIST: objects/VTBL/STBL - 6/35/0, count/pages swapped 18/18
COLLECTION SYSTEM:ARRAYLIST OF OBJECT SYSTEM:STRINGLIST: objects/VTBL/STBL - 2/17/0,
This example shows how the |
The following rules describe the compiler allocation outcomes when combinations of directives are specified for a class:
- The number of object slots allocated for a class
is never allowed to fall below
AbMin
for that class. - The number of object slots allocated for a class is not
allowed to exceed
Max
for that class. The only exception is ifMax
is less thanAbMin
. - In the absence of any MaxObjects settings,
Min
becomes the effectiveMax
. - If there is a combination of Sirius MaxObjects and Sirius MinObjects specification for a class, the
compiler allocates as follows:
Situation Object slots allocated Min < Max Min or greater There are three cases, which are also depicted in the figure below:
- If Min >= Native, Min are allocated (not to exceed Max).
- If Min < Native < Max, Native are allocated.
- If Native > Min, and Native >= Max, Max are allocated.
Max <= Min Max The compiler will try to allocate Min object slots, but it will "stop" when it reaches Max (by rule 2, Max is not exceeded).
Cases a
, b
, and c
in the figure above
are those described in rule 4, above. The figure shows that, if a combination of MaxObjects, MinObjects, and AddObjects compiler directives are specified, the actual object space allocation in VTBL you get depends on how
the compiler's Native
count (N
) of the needed object
instance slots compares to Max
and Min
,
the effective MaxObjects and MinObjects values.
Selectively compiling user methods
Sites that feature user-created classes can economize on server space consumption by modularizing their application code and by including user method definitions only if the methods are actually called.
SOUL classes incorporate a "header file" type of design: the declaration of classes is distinct from the code that implements the classes. This separation will let you package user classes in multiple procedures, one or more of which contain the declaration of the class definitions, while others contain the code for the various methods. Although the compiler needs the complete declaration to compile references to members of each class, the code that implements functions and properties need only be included if it is actually used in a particular procedure in the current compilation.
With this approach, you can avoid the extra server space accumulated by multiple includes of the same definition or method code within a single compilation of a complex program. You can even programmatically prevent such duplicate includes by using the !DUPEXIT SOUL macro.
Displaying object statistics
The OBJSTAT User 0 parameter controls the display of journal messages that contain user statistics about SOUL object usage per request. The messages specify server table usage (VTBL and STBL) and object-swapping counts per object class and summed for all classes.
Message format
You can set OBJSTAT to display object statistics after program compilation, evaluation, or both (as described below in Setting OBJSTAT). The layout for post-compilation messages is the same as that for post-evaluation messages, as described below and as shown in Sample object statistics:
- One message for each class of objects instantiated in the program, with this format:
MSIR.0884: [OBJECT | COLLECTION] classname: objects/VTBL/STBL - obj/vtb/stb, count/pages swapped osw/psw
- A single message that reports the sum of the counts of the preceding individual classes, with this format:
MSIR.0884: *TOTAL*: objects/VTBL/STBL - obj/vtb/stb, count/pages swapped osw/psw
Where:
classname | Identifies the name of the class for which space for object instances is allocated. System classes are prefixed with SYSTEM: . System enumerations are excluded because they are not stored in VTBL or STBL. |
---|---|
objects | Object instances for which server space is allocated for the indicated class (or for all classes) for the request. This space is allocated at compile time, thus separate from the actual number of run-time objects used.
The number of |
VTBL | VTBL units (32 bytes per unit) occupied by the objects . Each instance of an object in a given class requires the same amount of space: a fixed amount for an object header, and a non-fixed amount for each member variable (that is, every variable in the Public or Private — but not Public Shared or Private Shared — blocks).
The number of VTBL units allocated is
The |
STBL | STBL bytes occupied by the objects. Parts of some objects, such as string and longstring variable values, use STBL.
The number of STBL units allocated is |
obj, vtb, stb | The number, respectively, of objects , VTBL units, and STBL bytes.
Note: These amounts encompass all the space used for object instances, which includes some internal overhead. It does not include the space used for object references, that is, object variables. |
count | The count of object swaps: the number of times object instances of this class were swapped into or out of the server during the request.
The value of Note: A swap out counts as one, and a swap in as one, so a swap in and out counts as two. Accessing a global/session object counts as a swap in, since objects do not sit in the server between requests, so they need to be swapped into/out of CCATEMP. Swaps happen only during evaluation, so this number should always be zero in the post-compilation statistics. |
pages swapped | The number of 6144-byte pages swapped into or out of the server. This number should always be an integral multiple of count , and the multiplier should be one, except for very large objects (greater than 6144 bytes).
The value of |
osw, psw | Values, respectively, of count and pages swapped . |
Setting OBJSTAT
OBJSTAT is a typical Model 204 bitmask parameter that is also per-user and resettable. It contains the following bit options, two or more of which you can select by specifying the sum of their bit values:
X'00' | Display no OBJSTAT statistics; this is the default. |
---|---|
X'01' | Display post-compilation object statistics to the journal. |
X'02' | Display post-evaluation object statistics to the journal. |
X'10' | Display post-compilation object statistics to both the terminal and the journal. |
X'20' | Display post-evaluation object statistics to both the terminal and the journal. |
Note: X'22' is the same as X'20'; X'10' is the same as X'11'; and X'30' is the same as X'31', X'32', or X'33'.
You can set OBJSTAT in the User 0 stream, and you can reset it
with the Model 204 RESET command (for example, R OBJSTAT X'33'
)
or with the $Resetn function
(for example, $RESETN('OBJSTAT', $X2D('33'))
).
Sample object statistics
With OBJSTAT set to X'33', the following SirScan AD-line output displays after including a procedure that manipulates some objects. The post-compilation individual-class statistics and all-class totals are followed by the post-evaluation statistics and totals.
MSIR.0884: OBJECT LONG: objects/VTBL/STBL - 2/7/0, count/pages swapped 0/0
MSIR.0884: OBJECT PT: objects/VTBL/STBL - 2/18/0, count/pages swapped 0/0
MSIR.0884: OBJECT CELL: objects/VTBL/STBL - 2/20/0, count/pages swapped 0/0
MSIR.0884: OBJECT BOX: objects/VTBL/STBL - 2/75/144, count/pages swapped 0/0
MSIR.0884: COLLECTION SYSTEM:ARRAYLIST OF OBJECT PT: objects/VTBL/STBL - 3/25/0, count/pages swapped 0/0
MSIR.0884: OBJECT SYSTEM:STRINGLIST: objects/VTBL/STBL - 3/18/0, count/pages swapped 0/0
MSIR.0884: *TOTAL*: objects/VTBL/STBL - 14/163/144, count/pages swapped 0/0
MSIR.0884: OBJECT LONG: objects/VTBL/STBL - 2/7/0, count/pages swapped 571/571
MSIR.0884: OBJECT PT: objects/VTBL/STBL - 2/18/0, count/pages swapped 310/310
MSIR.0884: OBJECT CELL: objects/VTBL/STBL - 2/20/0, count/pages swapped 528/528
MSIR.0884: OBJECT BOX: objects/VTBL/STBL - 2/75/144, count/pages swapped 0/0
MSIR.0884: COLLECTION SYSTEM:ARRAYLIST OF OBJECT PT: objects/VTBL/STBL - 3/25/0, count/pages swapped 0/0
MSIR.0884: OBJECT SYSTEM:STRINGLIST: objects/VTBL/STBL - 3/18/0, count/pages swapped 0/0
MSIR.0884: *TOTAL*: objects/VTBL/STBL - 14/163/144, count/pages swapped 1409/1409
For a case where these statistics guide the tuning of the object allocation algorithm, see A MinObjects example.