next up previous
Next: Conclusions Up: Experiences with modularizing the Previous: Reduction of Stack Usage


Stack Reduction Results

To test the effectiveness of our changes to the core in reducing usage of stack we used the testsuite again, but with a twist. Using a special script we ran each of the 7879 tests multiple times, with an ever-shrinking stack, until it failed. The size of the stack for which a test failed first was recorded. The initial size of the stack was 48 K and reduced by 1 K per iteration.

Running this with unmodified and modified cores then allowed us to compare how the consumption of stack was changed by our modifications. The results of these comparisons for selected build variants are shown in the Table 5.

The first three columns in each these two tables list the minimal amount of stack required by any test during its execution, the maximal amount required by at least one test during its execution, and the average amount of stack required to execute a test.

For the values in the last three columns each configuration (except for the first) was compared to the configuration preceding it in the table. To facilitate this the system computed the difference in stack consumption for each test and then recorded minimal, maximal and average difference. A positive difference means that the configuration required less stack than the one it was compared to.


Table 5: Stack consumption changes
  Min Max Avg d/Min d/Max d/Avg
Base 31 48 31.227      
Stack (Zero) 27 39 27.449 0 21 3.779
Stack (Basic) 27 35 27.065 0 8 0.384
Stack (All) 27 35 27.065 -3 2 -0.001

The line ``Base'' in Table 5 refers to the unmodified 8.3.4 core. It was compiled with basic compiler optimizations (-O). The other three lines refer to the modular core with its non-recursive byte code engine. It was always compiled with basic compiler optimizations (-O), but different settings for the switches affecting the usage of the C stack. Which switches were activated is listed in Table 6. An entry of ``--'' means that the switch was not activated and set to its default value.


Table 6: Stack reduction switches
Macro No settings Basic setting Full setting
TCL_DSTRING_STATIC_SIZE -- 1 1
TCL_FMT_STATIC_FLOATBUFFER_SZ -- 1 1
TCL_FMT_STATIC_VALIDATE_LIST -- -- 1
TCL_FOREACH_STATIC_ARGS -- 1 1
TCL_FOREACH_STATIC_LIST_SZ -- 1 1
TCL_FOREACH_STATIC_VARLIST_SZ -- -- 1
TCL_RESULT_APPEND_STATIC_LIST_SZ -- 1 1
TCL_MERGE_STATIC_LIST_SZ -- -- 1
TCL_PROC_STATIC_CLOCALS -- 1 1
TCL_PROC_STATIC_ARGS -- -- 1
TCL_INVOKE_STATIC_ARGS -- 1 1
TCL_EVAL_STATIC_VARCHARS -- -- 1
TCL_STATS_COUNTERS -- -- 1
TCL_LSORT_STATIC_MERGE_BUCKETS -- -- 1
TCL_STRUCT_ON_HEAP n y y

We can see that the basic overhead of stack required by the test framework amounts to 31 K for the unmodified core. There are two tests breaking the initial limit of 48 K stack, these are ``interp-29.1'' and ``interp-29.2''. Both are testing the handling of the recursion limit of the Tcl core.

The introduction of the non-recursive engine alone (configuration ``Stack (Zero)'' reduces the average consumption of stack by nearly 4 K. Especially noteworthy is that now no test is breaking the initial limit of 48 K anymore, not even the two tests checking the recursion limit mentioned before. Actually these two tests now require nothing more than the new minimum overhead of 27 K stack, accounting for the reported maximal reduction of 21 K.

Adding the basic set of switches (configuration ``Stack (Basic)'') to shrink variables on the stack, or move to them to the heap reduces the consumption of stack by another near half K, bringing the reduction up to slightly more than 4 K on average. So these switches do have an effect, but not as much as the new byte code engine.

Setting all possible switches (configuration ``Stack (All)'') we find that this is actually slightly worse than using only the basic set. It is unclear however if this a measuring problem or a true worsening. It is also unclear if the expected further reduction is missing because the testsuite is not exercising these parts of the core, or if the affected variables cause a reduction which is too small to be measured at all.


next up previous
Next: Conclusions Up: Experiences with modularizing the Previous: Reduction of Stack Usage
[email protected]