Solstice Enterprise Manager 4.1 Developing C++ Applications Doc Set ContentsPreviousNextIndex


Chapter 13

Optimizing Performance

The high-level Portable Management Interface (PMI) provides many features that simplify the coding of an application. However, if you need fast response from an application, or if an application is controlling and monitoring a large number of managed objects, you need to tune the application to obtain optimum performance.

This chapter explains how to optimize the performance of your applications.

13.1 General Guidelines for Optimizing Performance

The high-level PMI provides many features that simplify the coding of an application. But using these features reduces the performance and efficiency of the application. Tuning at appropriate places improves the performance and efficiency of an application by:

To simplify tuning an application, code each time-critical section as a separate function call. To tune an application coded in this way, all you need do is replace a single function, rather than rewrite the entire application to improve its performance.

13.2 Selectively Activating Image Instances

Selectively activating an Image instance loads information only on attributes that are relevant to your application. By default, information on all attributes of a managed object is loaded when an instance of Image is activated. Loading information on all attributes increases network traffic and the amount of memory the Image instance uses.

To selectively activate an Image instance, call the boot function of the Image class, specifying only the attributes your application needs.

For more information on the boot function, refer to Section 5.4 Updating an Image Instance.

For more information on the Image class, refer to Chapter 5.

Code for selectively activating an Image instance is shown in CODE EXAMPLE 13-1.

CODE EXAMPLE 13-1   Selectively Activating an Image Instance 
...
#include <pmi/hi.hh>            // High Level PMI 
...
    Image channel_image(channel_name.data());
    if (channel_image.get_error_type() != PMI_SUCCESS) {
        cout << channel_image.get_error_string() << endl;
        return FALSE;
    }
...
    Array(DU) attrs;
    attrs = Array(DU)(1);
    attrs[0] = strdup("program");
    if (!channel_image.boot(attrs)) 
{
        cout << channel_image.get_error_string() << endl;
        return FALSE;
    }

In this example, only information on the program attribute is loaded when the Image instance is activated.

13.3 Filtering Events

Filtering events makes sure that the MIS forwards to your application only the events that are relevant to the application. Filter events to reduce the amount of network traffic between your application and the MIS it is connected to. By default, the MIS forwards all events it receives to your application.

For information on how to filter events, refer to Section 7.4 Filtering Events.

13.4 Writing Your Own Classes to Represent Managed Objects

Using an instance of Image to store all the data in a managed object simplifies the coding of your applications, but it does require a lot of memory. If memory is scarce, you can save memory by defining your own C++ class to represent managed objects locally in an application. For more information, refer to Section 5.12 Representing MIS Instances Locally in an Application.

13.5 Using the Low-Level PMI

Using the Album class to perform management operations on object collections increases network traffic and the amount of memory your application instance uses, particularly if your collections contain a large number of managed objects.

To improve the performance of your application, use the low-level PMI to perform operations on object collections. To keep the coding of your application simple, you can still use the high-level PMI for:

When you use the low-level PMI, the data you pass in function calls must be in ASN.1 format, which is the format that Solstice EM uses internally. If you are unfamiliar with this format, use the high-level PMI to produce a representation of your data in this format by:

For information on how to use em_debug, refer to Section 15.2 Monitoring Communications With the MIS.

When you have the information you need, modify your prototype to use the low-level PMI, copying the format of ASN.1 data types in the messages displayed by em_debug.

CODE EXAMPLE 13-2 shows code for getting information from an object collection. This example is equivalent to using the Album class to define the membership of an object collection by derivation.

CODE EXAMPLE 13-2   Getting Information From an Object Collection 
...
#include <pmi/sched.hh>            // Scheduler for applications 
without a GUI
...
GetReq *msg = (GetReq*)Message::new_message(GET_REQ);
    asap = (ApplMessageSAP *) em_mis.get_raw_sap();
 
    msg->id = asap->new_id();
    cout << "Deriving from localroot" << endl;
    // This is the actual_class. For get, set, and delete operations the class
    // of the object is not checked if this is given.
    msg->oc = enc("CMIP-1", "ObjectClass", "globalForm:{2 9 3 4 3 42}");
 
    DU remainder;
    msg->oi = fdn2oi(""); // localroot systemId branch
 
    if(!msg->oi)
    {
        cout << "fdn2oi failed" << endl;
        exit(1);
    }
 
    // Scope of all levels selected
    msg->scope =  MessScope(NTH_LEVEL, 1);
 
    char *filter = "item: equality: {objectClass, satellite}";
    msg->filter = enc("CMIP-1", "CMISFilter", filter);
    if (!msg->filter) {
    cout << "Filter encoding failed!" << endl;
    }
 
    // Set the attribute list to indicate that no attributes are of interest.
    // Only the object instances are received  - none of their attributes.
    // This is equivalent to an Album object with NO AUTOIMAGE.
 
    // If all attributes are of interest comment the following line.
    // This is equivalent to an Album object with AUTOIMAGE.
 
    // If some, but not all, attributes are wanted refer to boot.cc example.
    msg->attr_id_list.start_construct(TAG_SET);
 
    Callback mycb(data_return,0);
 
    // For the reply sent to this message, mycb will be called
    if(!asap->send(msg, mycb))
    {
        cout << "send failed" << endl;;
        exit(2);
    }
 
    last_response = 0;
    // last_response will be set after all the linked
    // replies are received
    do
    {
        dispatch_recursive(TRUE);
    }
    while(!last_response);
...

In this example, a CMIS Get request is sent to get the FDN of each instance of the satellite managed object class contained by the root object. An instance of the Callback class is initialized to handle the response received to this request. To ensure that the callback is called, dispatch_recursive is called in a loop while the application is still waiting for the last response.

CODE EXAMPLE 13-3 shows the definition of the callback handler for processing responses to the request sent in CODE EXAMPLE&nbs p;13-2.

CODE EXAMPLE 13-3   Callback for Handling Responses to a Get Request 
...
void data_return(Ptr userdata, Ptr calldata)
{
    Message *msg;
    asap->receive_response(ResponseHandle(calldata), msg);
    if(!msg) {
        printf("receive_response failed \n");
        exit(4);
    }
    GetRes* grmsg ;
    switch (msg->type()) {
        case GET_RES:
            grmsg = (GetRes*)msg;
            if (grmsg->oc) {
                // Note: This is stored in Q? A1- Must be stored somewhere,
                // A2- oc2name() etc calls dispatch_re which calls data_return()
                // each call is > 20 frame stack, for 10 it will > 200 etc....
                ocs.enq(new Asn1ValueElem(grmsg->oc));
            }
            if (grmsg->oi) {
                ois.enq(new Asn1ValueElem(grmsg->oi));
            }
            break;
        default:
            printf("Incorrect message type %d\n",msg->type());
            fflush(stdout);
            exit(5);
    }
    if(!grmsg->linked) {
        last_response = 1;
        printf("Last Respnse\n");
    }
}
...


Sun Microsystems, Inc.
Copyright information. All rights reserved.
Doc Set  |   Contents   |   Previous   |   Next   |   Index