Monday, November 8, 2010

QueryPerformanceCounter and GetTickCount functions , A Performance Tuning method

Title - QueryPerformanceCounter and GetTickCount  functions ,  A Performance Tuning method

Tip - QueryPerformanceCounter() / GetTickCount()  can be used to get the timing of  each function. Based on that we can tune the performance.

Details - The QueryPerformanceCounter Retrieves the current value of the high-resolution performance counter. But on a multiprocessor computer, it should not matter which processor is called. However, you can get different results on different processors due to bugs in the basic input/output system (BIOS) or the hardware abstraction layer (HAL). So in that case we can use GetTickCount functionality. But the precision of GetTickCount is limited to milliseconds.
  
Reference :

Posted By : Febil Chacko

Sunday, November 7, 2010

Profiling , A Performance Tuning method

Title -Profiling ,  A Performance Tuning method

Tip -The profiler is an analysis tool that you can use to examine the run-time behavior of your programs. By using profiler information, you can determine which sections of your code are working efficiently. The profiler can produce information showing areas of code that are not being executed or that are taking a long time to execute.
Because profiling is a tuning process, you should use the profiler to make your programs run better, not to find bugs. Once your program is fairly stable, you should start profiling to see where your code could perform better.

Details -Use the profiler to determine whether,
    * an algorithm is effective (timing),
    * a function is being called too many or too few times with respect to the problem domain (counting), or
    * a piece of code is being covered by software testing procedures (coverage).

Build the project for profiling :
Before using the profiler, you must build the current project with profiling enabled (equivalent to the command line setting LINK /PROFILE). If you want to perform function profiling only in the current project, you only need to enable profiling for the linker. If you want to do line profiling, you also need to include debugging information.

To build your project for function profiling
   1. On the Build menu, click Settings to display the Project Settings dialog box.
   2. Click the Link tab.
   3. In the Category drop-down list box, click General.
   4. Select the Enable Profiling check box.
   5. Click OK.
   6. On the Build menu, click Buildprojectname.exe.
Note   Selecting the Enable Profiling check box turns off incremental linking. To re-enable incremental linking, clear the Enable Profiling option.
To build your project for line profiling
   1. Perform the procedure to enable function profiling described earlier in this topic.
   2. Select the Generate Debug Info check box.
   3. Click the C/C++ tab.
   4. In the Category drop-down list box, click General.
   5. In the Debug Info drop-down list box, click Program Database or Line Numbers Only.
   6. Click OK.
   7. On the Build menu, click Buildprojectname.exe.
When the build is complete, the project is ready to be profiled.

To run the profiler from the development environment
On the Build menu, choose Profile to display the Profile dialog box

   1. In the Profile Type box, click one of the following option buttons:
          * Function Timing
          * Function Coverage
          * Line Coverage
          * Merge
          * Use Custom and the Custom Settings text box to run a batch file that contains profiler commands. See Run the Profiler from the Command Line for information on why you might want to batch and execute your own profiler commands. See Running a Custom Batch File for more information on specifying a batch file from the development environment.
          * Advanced settings is where you can specify PREP Phase I options.
   2. Click OK.

Function Timing Profile sample output
Func                  Func+Child               Hit
Time          %     Time              %      Count           Function
-----------------------------------------------------------------------------
53153.728  99.5  53314.866     99.8     56     CWinThread::PumpMessage(void) 
136.579       0.3      136.964      0.3     176   CWnd::DefWindowProcA(unsigned int,unsigned int,long)

Function Coverage Profile sample output
Covered Function:
    *    AfxEnableControlContainer(class COccManager *) (mfc42.dll)
    *    AfxFindResourceHandle(char const *,char const *) (mfc42.dll)
    *    AfxInitialize(int,unsigned long) (appmodul.obj)
    .    AfxMessageBox(char const *,unsigned int,unsigned int) (mfc42.dll)

Reference :

Posted By : Febil Chacko

Thursday, November 4, 2010

DLL Delay Loading

Tip -Use DLL delay loading to increase startup performance of an executable.

Details -Libraries are the way by which any system is built. We know that a library can be static or dynamic. In most of the situations, we use dynamic libraries. Usually when a loader program prepares an executable for execution, apart from other things, it will iterate the IAT (Import Address Table) of the executable and call the LoadLibrary() for each of the DLL found in the IAT. If an executable is linked to ten DLLs, then the loader will call ten LoadLibrary() calls. Additionally the same procedure will be done for each of the DLLs being loaded. In a big system with numerous executables that are linked to hundreds of DLLs, the startup performance will be affected by this DLL loading. In fact, the functions in these libraries may not be called by the executable during startup. Here we can save the DLL loading time by configuring candidate DLLs for delayed loading.

Delay load is a feature, that when used, will cause the DLL to be loaded only during the first invocation of any of its exported function. We can configure a DLL for delay load for both an EXE and DLL. This feature is invoked when the compiler builds the binary.

How To - The easiest way to do this is by using the /DELAYLOAD:dllname linker switch. This is supported starting from VC 6.0.

Higher versions of Visual Studio give more options such as programmatically specifying the DLLs for delay load. It also gives more flexibility such as unloading the delay loaded DLLs.

References:

Posted By : Mohammed Nisamudheen S.

Wednesday, November 3, 2010

Windows Thread Pool

Tip -We can use Windows thread pool for gaining performance in a multithreaded environment.

Details -In a multithreaded environment, we create several worker threads to perform various tasks in parallel.  Usually we create threads as and when required and exit the thread after finishing the job. In order to relieve the programmer from the thread creation and destruction tasks and to improve the performance, we can use the Windows thread pool. Windows has redesigned its thread pool architecture starting from Vista. Using this, we can execute a normal worker thread task without calling the CreateThread() API, in a thread. Briefly we can use the thread pool APIs to call a user defined function under the following situations.

  • Execute the function in a thread.
  • Execute the function during the timer intervals.
  • Execute the function whenever a kernel object signals.
  • Execute the function when an asynchronous IO is completed.
API -In order to execute a function in a separate thread in the pool, define a function with the following signature.

VOID CALLBACK AsyncFunction( PTP_CALLBACK_INSTANCE pInstance_i, PVOID pvContext_i );

Now call the following API, to execute the above function in a separate thread.

BOOL WINAPI TrySubmitThreadpoolCallback(PTP_SIMPLE_CALLBACK pThreadFun_i, PVOID pvData_i, PTP_CALLBACK_ENVIRON pEnv_i );

The above user define function will be passed as the first parameter to the thread pool API. 

References:

Posted By : Mohammed Nisamudheen S.

Monday, November 1, 2010

Slim Read-Write (SRW) Locks

Tip - A Slim Read-Write lock is a variation of the critical section object. The difference is that it permits multiple read locks at the same time.

Details - Usually we will be having a single writer thread and multiple reading threads. If we are using a critical section object for synchronization then each read thread will have to wait for the other read threads to leave the critical section. The SRW lock improves the situation by allowing multiple read locks by different threads at the same time. This will provide greater concurrency, especially on multi processors. When the writer thread wants to acquire the lock, it will wait for all the read threads to leave the SRW lock.

API - Following is the API to acquire and release a read lock.

AcquireSRWLockShared( PSRWLOCK SRWLock )
ReleaseSRWLockShared( PSRWLOCK SRWLock )

Following is the API to acquire and release a write lock.

AcquireSRWLockExclusive(PSRWLOCK SRWLock )
ReleaseSRWLockExclusive(PSRWLOCK SRWLock )

Performance - The following table shows the performance of a task that is performed in multiple threads using different synchronization mechanisms, on a dual processor system.
Threads/Milliseconds
Critical Section
SRWLock Shared
SRWLock Exclusive
Mutex
1
66
66
67
1060
2
268
134
148
1082
4
768
244
307
23785

Looking at the performance values, we can clearly see that there is a big performance gain for SRW locks when compared with a critical section object.

Limitations
There is no API like TryEnterxxx() as in the case of a critical section. A thread need to wait till it gets the requested lock. This limitation is only applicable to Windows Vista only. Windows 7 provides the TryAcquireSRWLockExclusive() and TryAcquireSRWLockShared().


The SRW locks cannot be acquired recursively. That means a thread cannot acquire multiple locks and then perform the corresponding number of releases. Currently this limitation is applicable to Windows Vista. This limitation might be removed higher versions.


Platform
Minimum requirement is Windows Vista.


References:

Posted By : Mohammed Nisamudheen S.

Sunday, October 31, 2010

Dynamic Data Breakpoint

Tip - Putting dynamic data breakpoints.

Details -We know that there are two kinds of breakpoints. First is the code break point. The second type of break point is the data break point that can be set on variables. We can set a data break point on any (global, member and local) variables so that when it is read/written, the execution will be suspended. Usually data breakpoints are useful in detecting application crashes. In that, the crash occurs at one point and it might be due to an invalid memory access done at a different point in code. In this case we can put a dynamic data break point on the suspected variables.
When we are working with big systems, with hundreds of DLLs, it might not be practicable to put breakpoint by first attaching the required process to a debugger, break at some point and then put the code or data breakpoint. Also, the data might be allocated dynamically from a thread that is created at runtime. So it calls for dynamic breakpoints.
Both the code and data breakpoints can be set dynamically, without the help of a debugger. During runtime, when any one of these breakpoints is encountered, Windows OS will generate an Unhandled Win32 Exception.

How To -Code breakpoints can be dynamically set using the DebugBreak() API. The compiler will generate an int 3; assembly instruction.
The data breakpoints are set by the means of the context information of a thread. Apart from other things, the context contains debug registers. The number of data break points that can be set to a thread is limited by the number of debug registers available. We can also specify on what kind of access (read/write) it should break.
 In order to set a data breakpoint, following steps are done.
1.     Get the current thread context.
2.     Find the available register.
3.     Set the following information to the thread context.
(ア)             Starting memory address of the data.
(イ)             Number of bytes to be monitored for access.
(ウ)             Read/Write flag information. This is because we can tell whether to break on data read or data write. 1 for read and 3 for write.
(エ)             Set the enable/disable. 1 for enable and 0 for disable.
4.     Set the updated context.
The above steps will cause the breakpoint when the data is modified from a single thread.
What if the data is allocated from one thread and it is being accessed from different threads? In order to monitor a piece of data for read/write access from all the threads, we need to perform the above steps for each thread. One way to achieve this is to write a DLL and make use of the thread-attach notification.

Sample Implementation
The attached zip contains a DLL and a test application. The DLL exposes two APIs. One is to set the breakpoint and the other is to unset the breakpoint. During the set operation, it will update the current thread context and will keep the address, size etc inside a map. When the DLL receives a thread attaché notification, it will iterate the map and set the breakpoint for the new thread by updating its context information.


Sample application Download


References:
http://www.morearty.com/code/breakpoint

Posted By : Mohammed Nisamudheen S.


Thursday, October 28, 2010

Dr Watson Debugger

Tip - Dr. Watson for Windows is a program error debugger that gathers information about your computer when an error (or user-mode fault) occurs with a program.

Details - Dr Watson is a windows tool which automatically creates log and dump files when the application crashes. The Dr Watson error logs are useful for error diagnostics when no other particular log informations are not available. The dmp files available with Dr Watson can be analysed through debugging applications such as WinDbg.

By Default the error dumps of Dr Watson will be available at the path
C:\Documents and Settings\All Users\Application Data\Microsoft\Dr Watson\user.dmp

It is not necessary that Dr Watson is the default application that will be started when a application crash occurs. We can ensure the same using the Registry path HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\AeDebug.

If the default debugger is not Dr Watson and you want to use Dr. Watson instead go to the command prompt and type the command drwtsn32 -i to start Dr. Watson. Typing -i causes the necessary changes to be made to the registry.

Interesting fact - The debugger is named after Doctor Watson of Sherlock Holmes fame, the idea being that it would collect error information following the problem. The original name of this tool was "Sherlock".

References - 

Posted By : Xavier K Joseph