Tips Techniques Tips on Using DSS Threads

Tips on Using DSS Threads

 * Tip:While threads are very convenient for structuring an application, they come with a cost. Each thread has its own stack and associated data structures that add to the memory requirements of the application. In addition, threads are usually scheduled in round-robin fashion, with each thread getting its turn to run. Thus the more active threads there are, the longer a given thread may have to wait between the times it gets to run. Also, creating and destroying threads takes time that could be spent doing real work.


 * Technique:Conserve threads whenever possible. Instead of creating a thread whenever a piece of work needs to be done and destroying it when the job is done, consider using a thread-pooling strategy where threads that have finished their assignment check a queue of jobs for more work, waiting on a condition variable if there is no work.


 * Tip:A thread can be interrupted at any moment and another one scheduled If a thread is interrupted while it holds an important lock and another thread tries to grab the lock and gets blocked, time is wasted on context switching back and forth. The second thread is not going to make any progress until the first one releases the lock.


 * Technique:Try to avoid holding locks unnecessarily. Also, reduce the chances of this happening by holding locks for shorter times and by using finer-grained locks (use different locks for logically separate structures rather than one global lock). Of course, you have to trade this benefit against the cost of locking and unlocking. It is possible to go too far and spend all your time locking and unlocking hundreds of fine-grained locks.


 * Tip:There are some differences in performance characteristics of the different protocol sequences and their associated transports Connection-oriented (CN ) (for example, ncacn_ip_tcp) is quicker to detect a down server, but does not scale as well as datagram (DG) (for example, ncadg_ip_udp), since the server will need a separate connection (and connection receiver thread) for each concurrently active client


 * Technique:At small data sizes, CN and DG have similar performance, but CN is a bit faster at large data sizes.

Tips on Using DSS Remote Procedure Calls

 * Tip:The remote procedure call (RPC) component gives you very precise control over the security level to use for making RPCs. However, security does not come without a performance cost, so your application should use the minimum level of security that meets requirements. Connect level is not significantly different from none, but call level costs roughly 5 percent more than connect. Packet level is going to cost much more, increasing with the size of the parameters passed in the RPC. Integrity and privacy levels can be very costly for large data.


 * Technique:If you are going to be doing a series of RPC calls over time, you can speed things up by using a context handle, which will cause the RPC run time to keep an active connection between client and server. This solution avoids the cost of connection setup and tear-down (typically done after about 10 seconds of inactivity).

Tips on Using the Interface Definition Language

 * Tip:When you use the Interface Definition Language (IDL) to define the interfaces to your application, minimize the time spent marshalling and unmarshalling passed parameters. If an RPC returns a pointer as an out parameter, the client-side unmarshalling routines will need to allocate memory for that parameter.


 * Technique:Use simple structures and avoid pointers. Where possible, use reference pointers rather than full pointers - in many cases reference pointers do not require memory allocation. You can reduce the number of pointers by flattening your data structures, replacing a pointer to an object with an instance of the object instead.


 * Tip Don't transfer data you don't really need or use. It is better to use different data structures for different calls rather than complex one-size-fits-all structures with fields that many calls don't use.


 * Technique:Instead of returning data back from one call to be passed back in subsequent calls, think about caching that data in a context handle. Also, use variable-length conformant arrays instead of maximum-sized fixed-length arrays (for example, 1,024-byte name fields sized to handle the maximum possible name). It is a waste of time to copy all 1,024 bytes for a 10-byte name. In addition, if the client connects to the server via a slow link (for example, a dial-up link) it will take a lot longer to send those extra bytes across the wire.


 * Tip:Convert large complex structures into small opaque structures for faster marshalling.


 * Technique:Try using transmit_as to convert large complex structures into small opaque structures.