Pegasus Enhancement Proposal (PEP)

PEP #: 255

PEP Type: Function

Title: Reducing Pegasus Code size and static memory usage

Version: 1.0

Created: 8 May 2006

Authors: M. Brasher, K. Schopmeyer

Status:  Version 1.2 Approved by Architecture Team. (1.3 approved with readme added)

Version History:
 
Version Date Author Change Description
1.0 8 May 2006 M. Brasher, K. Schopmeyer Initial Submission
1.1 11 May 2006 Same Minor Updates to clarify changes proposed
1.2 1 June 2006 Same Respond to comments in V 1.1. This version approved by Arch Team
1.3 1 Aug 2006 Same Add readme for review.
1.3.1 14 Dec 2006 Same Incorporate comments into 1.3 creating 1.3.1 representing architecture Team Approval with Readme included.


Abstract: This PEP proposes a set of changes to create a major reduction in the code size of OpenPegasus without reducing functionality.

 

NOTE: Version 1.3 (with comments) of this PEP was approved for Pegasus 2.6 by the architecture team in ballot 116


References

1. PEP 253 - Concept PEP on Pegasus size and resource reduction.

 

1. Definition of the Problem

Pegasus today is large enough that it has proven to be a problem in smaller systems, particularly embedded systems.  It was generally felt that both dynamic memory usage and static memory usage needed to be reduced.

This PEP is concerned with the reduction of code size.  It does NOT attempt to cover any of the other static memory reduction issues discussed in PEP 253 such as:

  1. making functional features optional.

Also, this PEP is aimed only at the code reduction, not at the work defined in PEP 253 for dynamic (heap) memory usage. Thus the issues like:

  1. reducing the size of heap usage
  2. Setting limits to the size of heap usage.

are not addressed in this PEP.

Today the Pegasus static code size is approximately as follows:
The overall current OpenPegasus server  footprint (on Linux IX86) is about 6.8 MB broken down as shown in the following libraries. Note that this does not include some options such as SLP nor does it include the non-Control providers.
Library Size bytes Percent
libpegservice.so.1 18,209 0.3%
libCIMOMStatDataProvider.so.1 24,681 0.4%
libpegqueryexpression.so.1 26,123 0.4%
libCIMQueryCapabilitiesProvider.so.1 33,702 0.5%
cimserver 46,921 0.7%
libNamespaceProvider.so.1 50,225 0.7%
libConfigSettingProvider.so.1 53,188 0.8%
libUserAuthProvider.so.1 58,655 0.9%
libpeghandlerservice.so.1 60,171 0.9%
libpegquerycommon.so.1 65,785 1.0%
libpegexportserver.so.1 83,835 1.2%
libProviderRegistrationProvider.so.1 91,809 1.4%
libpegwql.so.1 93,440 1.4%
libpeguser.so.1 100,735 1.5%
libpegauthentication.so.1 102,496 1.5%
libInteropProvider.so.1 139,016 2.1%
libpegprm.so.1 168,833 2.5%
libpegprovider.so.1 192,759 2.8%
libpegconfig.so.1 212,521 3.1%
libDefaultProviderManager.so.1 262,118 3.9%
libpegclient.so.1 270,444 4.0%
libpegrepository.so.1 363,288 5.4%
libpegprovidermanager.so.1 366,652 5.4%
libpegindicationservice.so.1 398,459 5.9%
libpegcql.so.1 637,279 9.4%
libpegserver.so.1 823,987 12.2%
libpegcommon.so.1 2,025,038 29.9%
TOTAL 6,770,369  
In addition the CMPI provider manager is 602, 028 bytes. Note that this does not show up in the above list because it is not defined in the link.

 

NOTE: The footprint is heavily dependent on a number of characteristics such as:

Therefore, please use the above numbers as relative rather than absolute sizes.  The size information was gathered using a tool written by  Inova Development that provides size and relationship information on object, shared library, and executable files in a *nix system. Thus, the complete set of szes above was generated with one inspection of the cimserver executable.  
 

2. Proposed Solution

Requirements for this PEP

1. Significant reduction in both the object sizes and runtime code memory usage.  We would like to set a goal of 40% reduction.  This means reducing the code size of the basic Pegasus environment from about 6.8 meg to 3.7 meg.

2. Not remove any functionality.  Pegasus at the conclusion of this work would pass the same test set that it does now.

3. No reduction in performance.

4. Provide as an option the ability to be built exactly as it is now.  Any code changes in modules would be permanent but any linking changes would be considered optional.

5. The techniques are portable across all Pegasus environments or are automatically disabled on those environments where the tools to not allow them to be implemented.

6. Maintain binary compatibility for both the provider and clients.

Proposed Changes

The following it the list of techniques we propose to implement to reduce the overall code size:

 

1. Provide as an option a static build rather than the current dynamic build with a very small executable and an extensive set of shared libraries.   The shared library build model (today Pegasus builds one shared library for each directory of source files as shown above) is very convenient for developers in that the rebuild time is very limited however, shared libraries create extensive memory use overhead because

a) all the object files in the source directory must be in the shared library,

b) the symbol table sizes are very large because of the late binding

c) Shared libraries use position-independent code making there size larger than the corresponding function integrated into a static build.

  We propose to add an option to build multiple directories into a single executable rather than many different shared libraries.  Obviously one cannot simply build all of the environment into a single executable because some of the libraries are required for providers also and building them into the CIMServer would actually cause extra overhead with the objects duplicated between server and providers.  Therefore we propose to create a structure where a flag in the Makefile for each directory will determine if it is to be part of the static serve build or shared.  Further, there will be a flag to enable or disable the complete static build.

 

This will be done so that the Makefiles themselves define which are to be built into the static build and there is a single environment variable that defines whether or not the build is to be static or dynamic.

 

2. Reduce symbol usage in the link.  In order to implement windows linking a set of macros was implemented to provide for the windows export symbol, import symbol paradigm.  However, in the *nix world we left the environment with all symbols exported because there was no need for the export/import paradigm.  we can reduce code size by simply making use of these macros in the *nix linking environment.

 

3. Code refactoring.  There were several areas where extensive memory reduction can be achieved simply with code refactoring.

 a. Throwing exception is expensive.  Typically each exception is about 500  bytes of code.  Where there are large numbers of very similar exceptions, they can be consolidated into a function and called.  The use of the MessageLoaderParms further expands this by another 500 - 1000 bytes.  Creating a function to execute the MessageLoaderParms and throw and calling this from the place in the code where the exception is to be executed can save memory in those cases where there are a large number of very similar exceptions in a single component.  While there are a number of modules where extensive memory can be regained by this technique, this work concentrated on CQL and reduced the size of the CQL functions by 300,000 - 500,000 bytes.

 b. Because the tracer is used extensively throughout the server environment, size reductions in the macros for tracer can achieve significant savings.  The changes to be proposed save about 300,000 bytes.

4. Breaking up the Common Directory - Common contains a number of components that are not required by clientsWe created a protocol directory and moved a number of functions that are not used in from common to this directory. There were two possible advantages i) the protocol code is really server code and does not apply to the providers, ii) we felt that it might be possible to break the protocol functionality into client/server/listener.  Note that it is NOT our intent to use this as the means to completely revamp the common directory, simply to make those changes that will help object sizing.

 

5. Removed extra library symbol inter-references that were not needed and that caused problems when trying to separate out the static from dynamic functionality.  In particular we removed a number of inclusions of the client in link definitions in other libraries that were not needed.

 

Expected Results

 

The work to date is preliminary and should be considered a prototype of the changes that can be achieved.  However, to date on a typical linux system the code size has been reduced from the 6.;8 mb shown above to slightly less than 3.5 mbs, almost 50% smaller.

 

Generally about 50% of the savings is the static libraries, 40% is the code refactoring that has been done to date (Tracer, CQL, etc.) and 10% is other miscellaneous changes like the symbol reduction

 

 

Proposed Implementation

 

We propose to implement this and integrate it into Pegasus as a number of smaller steps to avoid one big change.  We will implement a group of changes and propose the changes to be integrated into Pegasus with a pegasus bug.  This appears to be less problematic than making all of the changes into a single branch and reviewing that branch.  If the changes are small, we can simply do it as diffs.  For more extensive changes, we will create a branch for review.

 

Generally we would separate out:

1. The symbol reduction changes.

2. The static build

3. The individual module refactoring.

 

The implementation includes adding a readme to the source root directory (readme.SizeReduction) that defines the basic means available to control footprint and the things that must be changed to execute a static build.

The readme as committed is duplicated in section 3 of this document.

 

We will not really see the overall savings until we get all of these individual changes into the CVS.

ISSUES TODAY

There are no major issues with this work today.  However, it is prototype and there is a significant amount of work to get this moved from prototype status to being able to compile and run on the full set of Pegasus platforms.

Since this complicates the Pegasus build process and gives the users a new set of alternatives, there is the need for something more than simply the new files.  It is proposed that a HOWTO be generated for the Pegasus build process defining the alternatives, and how to build both the static and dynamic models.

There may be one issue in measuring the gains.  Tools were written specifically to help measure the code size on linux as part of this work and there are not plans to either make these tools available generally within Pegasus or to port them beyond the linux platform.

3. Readme for this Work

TITLE: HOWTO REDUCE PEGASUS STATIC FOOTPRINT

Author: M. Brasher, Karl Schopmeyer

This HOWTO describes how to build Pegasus for the smallest possible footprint.
These steps will show you how to reduce the object file size as well as the disk
size.

COMPILER ISSUES

1. When using GCC, always use 4.0 or later. There are two advantages:

(*) GCC does a better job of optimizing C++ for size.

(*) Pegasus limits symbol visisibility from shared libraries using
special features of GCC 4.0 and later.

2. If you can't use at least GCC 4.0, at least try to use GCC 3.0 or
better. GCC 3.0 introduced the -fno-enforce-eh-specs option, which
reduces the object code size of Pegasus by 20%.

3. On 64-bit Intel systems, build 32-bit to save around 30% of the
footprint (64-bit code is large since the operands are twice as
long). This technique of course will produce slower code.

REPOSITORY SIZE REDUCTION

1. Configure Pegasus to use a binary CIM repository. This is done by
setting the PEGASUS_REPOSITORY_MODE environment variable to BIN.
This technique will improve the performance of the repository. There is
a readme that describes this feature.

2. Configure Pegasus to compress the CIM repository. This is done by
setting the PEGASUS_ENABLE_COMPRESSED_REPOSITORY environment variable
to true. This technique will slightly degrade the performance of the
repository. There is a readme that describes this feature.

COMPILE OPTIONS

1. Be sure that the PEGASUS_DEBUG environment variable is not defined
when you build Pegasus. Otherwise, you will end up with a much
larger image.
2. Define PEGASUS_NO_FILE_LINE_TRACE to eliminate __FILE__ and
__LINE__ macros from tracer expansion. This reduces the overall size
by about 50k but by not including the line and file information into
the code. However, it means the the resulting traces do not have this
information in the trace output

3. Turn off the compile of the trace completely. The flag PEGASUS_DISABLE_TRACE
will force the compile without any of the trace code. This can save at least
100k but means that there is no means to trace including the XMLIO traces.

4. Define the PEGASUS_OPTIMIZE_FOR_SIZE environment variable
that causes Pegasus to build with -Os rather than -O2.

5. Disable use of OOP. This eliminates the extra use of memory that occurs because of
the extra process created to load providers.

STATIC BUILD VS. DYNAMIC BUILD

Originally Pegasus was built with a series of dynamic libraries, one for each
source directory (common, WQL, CQL, etc.). While this has proven a good tool
for developers the result is a significantly larger footprint for a number of
reasons. See PEP 253 for more informaton. Today you have the choice of building
the dynamic version or a static build which results in a much smaller footprint.
Generally the static build can save up to 40% in footprint.

The same basic build mechanism is used for both static and dynamic builds
with the choice being controlled by the use of two variables:

PEGASUS_USE_STATIC_LIBRARIES - The environment variable
PEGASUS_USE_STATIC_LIBRARIES if it exists will result in a a static build.
In order to determine which of the libraries go into the static build, a
second variable is used in the Makefile for the libraries that are to be
included in the executable.

STATIC - Setting the variable STATIC=1 in the Makefile for a Pegasus
component causes that component to be included in the static executable
instead of building a shared library.

As part of the definition of the static build mechanisms into the build
environment, a lot of work was put into determining which of the existing
libraries could logically be in the executable since this means that they
are NOT available as shared libraries for use with providers and clients.

Currently the following libraries are in the static build as supplied with
the CVS Pegasus 2.6 checkout. Different users may elect to either add or remove
some of these libraries from the static build depending on their needs for
the availability of shared libraries for providers or clients..


NOTE: This list may change with time.

./src/Pegasus/Server/Makefile:STATIC=1
./src/Pegasus/Server/ProviderRegistrationManager/Makefile:STATIC=1
./src/Pegasus/Config/Makefile:STATIC=0
./src/Pegasus/Security/Authentication/Makefile:STATIC=1
./src/Pegasus/Security/UserManager/Makefile:STATIC=1
./src/Pegasus/WQL/Makefile:STATIC=1
./src/Pegasus/ProviderManager2/Makefile:STATIC=1
./src/Pegasus/ProviderManager2/Default/Makefile:STATIC=1
./src/Pegasus/IndicationService/Makefile:STATIC=1
./src/Pegasus/ControlProviders/QueryCapabilitiesProvider/Makefile:STATIC=1
./src/Pegasus/ControlProviders/NamespaceProvider/Makefile:STATIC=1
./src/Pegasus/ControlProviders/Statistic/Makefile:STATIC=1
./src/Pegasus/ControlProviders/UserAuthProvider/Makefile:STATIC=1
./src/Pegasus/ControlProviders/InteropProvider/Makefile:STATIC=1
./src/Pegasus/ControlProviders/ConfigSettingProvider/Makefile:STATIC=1
./src/Pegasus/ControlProviders/ProviderRegistrationProvider/Makefile:STATIC=1
./src/Pegasus/Repository/Makefile:STATIC=1
./src/Pegasus/ExportServer/Makefile:STATIC=1
./src/Pegasus/HandlerService/Makefile:STATIC=1
./src/Pegasus/Query/QueryExpression/Makefile:STATIC=1
./src/Pegasus/Query/QueryCommon/Makefile:STATIC=1
./src/Pegasus/CQL/Makefile:STATIC=1
./src/Service/Makefile:STATIC=1

To create the static build instead of the dynamic build:

1. Set the PEGASUS_USE_STATIC_LIBRARIES environment variable to 1 to
cause Pegasus to use static libraries where appropriate (rather than
dynamic libraries).

2. Rebuild.
 

4. Rationale

5. Globalization Checklist

No changes to any messages are planned for this work
 
ID Globalization Requirement Planned?

(Yes/No)

Comments
1      
2
3
4

 

6. Platform Considerations

This implementation is expected to be platform independent.  Since the work involves characteristics of the build process, particularly the linker it is expected to create some additional work during the integration phases to get the static links working in all of the Pegasus build environments.

 

Note that we do not expect the gains to be uniform accross all platforms because of the differences between linkers, etc. on different platforms.

7. Test Plan

Since this work is not expected to change any existing functionality, there are no changes to functional tests planned.  It is expected that the existing functional tests will suffice.  However, since this creates a whole new alternative for linking, it would appear that an additional test of the new linking alternatives will be required at least to link statically and to step through at least  the short functional tests.

Schedule

Status of the work to date

This work has been largely prototyped.  The prototype code will be available in a Pegasus branch shortly after this PEP is put into the review schedule

Planned Schedule
 
PEP  Milestone Planned Date Revised Date Actual Date Comments
Functional PEP Approval (this PEP) May 2006 June 2006
Code Available in CVS Branch May 2006 June 2006
Request to Arch Team for Merge of Branch June 2006
Functionality Complete (FC) June 2006
Certification Test Complete (CTC) TBD

 

Discussion

<Additional information from discussions,  reviews, and decisions of the steering committee and architecture team can be recorded here. Information in this section is to help reviewers but MUST also be reflected in the Proposed Solution / Rationale, etc. sections. This section is for information only during the review process.>

 

V 1.2 from V 1.1

[ (e_boden) Note that this dir also has much of OpenPegasus external ifc defnition (& impl.). Perhaps that should be broken out also.
(k_schopmeyer) We were not trying to create a general reorganization of common with this fix, simply sort out issues that are pertinent to size reduction. Today there are different perceptions/goals for common revamping. Our goals are to create a more effective static build. For others, it is the aesthetics of the organization of the source files into smaller categories independent of the object file/library structures. I think that the general reorg ought to be its own PEP>
¤148]
4. Breaking up the Common Directory - Common contains a number of components that are not required by clientsWe created a protocol directory and moved a number of functions that are not used in from common to this directory. There were two possible advantages i) the protocol code is really server code and does not apply to the providers, ii) we felt that it might be possible to break the protocol functionality into client/server/listener.

[ (a_dunfey) I assume this 50% savings includes the option of creating static libraries instead of shared/dynamic libraries. Do you have a sense of what the savings are if the Pegasus libraries are still built as dynamic libraries?
(k_schopmeyer) Generally about 50% was the move to static libraries. 40% general refactoring (CQL, tracer, etc.) and about 10% was other miscelaneous changes.
¤154]
The work to date is preliminary and should be considered a prototype of the changes that can be achieved.  However, to date on a typical linux system the code size has been reduced from the 6.;8 mb shown above to slightly less than 3.5 mbs, almost 50% smaller.

[ ¤155]  

[ (e_boden) Is this planned to be merged into the main trunk eventually? If so, what is expected timeframe?
(k_schopmeyer) We want to do this in the normal way. Approve this pep, review the TASK branch and then merge this branch. We have set generally the dates below.
¤156]
NOTE: The code for this change will be maintained in a CVS TASK branch PEP255-CodeReduction

[ (e_boden) Good idea. When will this HOWTO be available? Probably when this change is committed to PEP255_odeReduction branch, yes? When is that expected?
(k_schopmeyer) We will have to do this and put it into the branch so that it will be part of the branch review before merging. June is the level of timeframe we set for this.
¤159]
Since this complicates the Pegasus build process and gives the users a new set of alternatives, there is the need for something more than simply the new files.  It is proposed that a HOWTO be generated for the Pegasus build process defining the alternatives, and how to build both the static and dynamic models.




 

Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
EMC Corporation; Symantec Corporation; The Open Group.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.



 
 

Template last modified: March 26th 2006 by Martin Kirk
Template version: 1.11