Click here to Skip to main content
15,904,348 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
AnswerRe: derived from two classes..how to? Pin
Dominik Reichl14-Apr-03 8:39
Dominik Reichl14-Apr-03 8:39 
GeneralThank you Pin
ns14-Apr-03 8:40
ns14-Apr-03 8:40 
GeneralCan't run compiler after install on Win2000 Pin
jimNLX14-Apr-03 8:24
jimNLX14-Apr-03 8:24 
GeneralRe: Can't run compiler after install on Win2000 Pin
Chris Richardson15-Apr-03 8:49
Chris Richardson15-Apr-03 8:49 
GeneralMacros in Visual Studio 7.0 Pin
Anonymous14-Apr-03 7:14
Anonymous14-Apr-03 7:14 
GeneralRe: Macros in Visual Studio 7.0 Pin
Gary Wheeler14-Apr-03 10:30
Gary Wheeler14-Apr-03 10:30 
GeneralRe: Macros in Visual Studio 7.0 Pin
billb211214-Apr-03 10:56
billb211214-Apr-03 10:56 
GeneralSlow CreateCompatibleBitmap() and BitBlt() Pin
Dean Michaud14-Apr-03 7:00
Dean Michaud14-Apr-03 7:00 
I am experiencing extremely slow performance when using the MFC CBitmap::CreateCompatibleBitmap() and CDC::BitBlt() to copy compatible bitmaps between device contexts. Sometimes the calls are extremely fast, as expected from the wealth of documentation that recommends using memory bitmaps to optimize graphics. However, they are frequently slow, meaning that a single call to the either method takes approximately 0.5 seconds (sometimes more), which is obvious to our applications’ users.

I need to understand why some calls to these two methods are so slow and what we can do to prevent this from happening.

The zip file I have attached contains a DevStudio 6.0 MFC application with a few lines of code added to show the problem.

Test Procedure.
1) Run the application.
2) Resize the view - larger windows fail sooner.
3) Use File/DC Test to bring up the test dialog
4) Press the Blit button repeatedly, and look at the time reported in the message on the dialog. After a while, it will suddenly be much slower.

Test Implementation.
The application stores a number of CDC's and CBitmap's that are all the same size and compatible with the CView's CDC. On the first blit button press there is one CDC/CBitmap pair, then two on the second, etc. Each time the button is pressed, the old CDC/CBitmap's are destroyed, and new ones are created. The first CDC is BitBlt’ed to the second, the second to the third, etc, and finally the top CDC is blitted to the screen. Basically, this is done in two simple functions, controlled from the dialog callback:

CDeviceContextBufferCollection::CreateBuffer() - 5 Lines of Code
CDeviceContextBufferCollection::Copy() - 7 Lines of Code
CDCDrawer::OnBlit() - < 20 Lines

All the other code is for house keeping, and there is not much of it. The application was created with the MFC application wizard and is largely unchanged.

The times for each method are measured using a high performance timer, and are shown on the dialog. The time for each BitBlt() is also measured and sent to the TRACE window and can be seen when debugging.

For the first few executions, both calls are fast. However, at some point their performance will degrade. The trace output will show that some BitBlt()s are still very fast and some now are very slow. Note that all of these timed BitBlt()s are from one memory bitmap to another (i.e. not to the screen) and all the CDC's and CBitmap's are compatible (i.e. there are no DIBs).

Sample Execution:
Machine Info: P4 1.4GHz, Screen size 1600x1200, 16-bit color depth, 512Mb memory, 512Mb graphics card.

With the application Maximized, trace window output:

BitBlt took 741.828920ms
BitBlt took 38.999929ms
BitBlt took 14.086707ms

This shows that one BitBlt() took almost 3/4 seconds; the other two were quick. The first one (the slow one) is copying between two memory bitmaps; the new one is also two memory bitmaps, but is faster, and the last time, which is the fastest, is between a memory bitmap and the screen.

With a smaller window more bitmaps have to be allocated before it fails:

BitBlt took 0.016483ms
BitBlt took 0.016483ms
BitBlt took 0.012571ms
BitBlt took 0.012292ms
BitBlt took 0.011733ms
BitBlt took 0.012013ms
BitBlt took 0.012013ms
BitBlt took 0.011733ms
BitBlt took 0.012013ms
BitBlt took 246.562622ms
BitBlt took 10.034516ms
BitBlt took 2.872153ms

Again, there are lots of fast BitBlt()s and one very slow one; BitBlt()ing to the screen remains fast at 3 ms.

Once a particular BitBlt() is slow, then copying between that pair of CDC will always be slow. This behaviour is not really shown by the test application, as the CDC's and CBitmap's are destroyed and recreated on each iteration. Once a 'slow' CBitmap has been allocated, then next one allocated will often be slow too, sometimes is fast.

These times are typical on my machine, when it has just been rebooted, and Task Manager shows memory usage at around 100Mb (on the 512Mb machine). Hence I do not believe it is memory fragmentation/virtual memory issue. When the CView is not maximized, each CBitmap is relatively small (< 1Mb) so allocating 20 or so should not be a big deal. The same issue is seen on a variety of machines / OSs, and general older machines fail sooner. When the performance is good, Task Manager does not register any CPU usage; as soon at it is bad, CPU usage goes to 100 %.

The same application has been run on several other computers. I discovered that the behavior is slightly different between the different machines. Some machines had the CreateCompatibleBitmap() method being always fast and the BitBlt() degrading in performance. Other machines had both methods equally bad.

The real application requires several memory bitmaps to optimize z-layer drawing, more than two. Our simple test application gives poor performance when two are allocated. Using memory bitmaps and compatible CDC's is described everywhere as a method of gaining good performance. What are we doing wrong?

Download dctest.zip (~28k)

: Dean 'Karnatos' Michaud
GeneralMultiple inheritance Pin
Gary Kirkham14-Apr-03 5:42
Gary Kirkham14-Apr-03 5:42 
GeneralRe: Multiple inheritance Pin
Navin14-Apr-03 5:50
Navin14-Apr-03 5:50 
GeneralRe: Multiple inheritance Pin
Gary Kirkham14-Apr-03 5:58
Gary Kirkham14-Apr-03 5:58 
GeneralRe: Multiple inheritance Pin
Maximilien14-Apr-03 6:03
Maximilien14-Apr-03 6:03 
GeneralRe: Multiple inheritance Pin
Gary Kirkham14-Apr-03 7:26
Gary Kirkham14-Apr-03 7:26 
GeneralRe: Multiple inheritance Pin
Tim Smith14-Apr-03 6:08
Tim Smith14-Apr-03 6:08 
GeneralRe: Multiple inheritance Pin
Maximilien14-Apr-03 6:28
Maximilien14-Apr-03 6:28 
GeneralRe: Multiple inheritance Pin
Gary Kirkham14-Apr-03 7:43
Gary Kirkham14-Apr-03 7:43 
GeneralRe: Multiple inheritance Pin
Tim Smith14-Apr-03 9:51
Tim Smith14-Apr-03 9:51 
GeneralRe: Multiple inheritance Pin
#realJSOP14-Apr-03 6:42
professional#realJSOP14-Apr-03 6:42 
QuestionCreateProcess ??? Pin
will138314-Apr-03 5:38
will138314-Apr-03 5:38 
AnswerRe: CreateProcess ??? Pin
Rage14-Apr-03 6:08
professionalRage14-Apr-03 6:08 
GeneralRe: CreateProcess ??? Pin
will138314-Apr-03 6:27
will138314-Apr-03 6:27 
GeneralRe: CreateProcess ??? Pin
Rage14-Apr-03 6:43
professionalRage14-Apr-03 6:43 
GeneralRe: CreateProcess ??? Pin
Rage14-Apr-03 6:45
professionalRage14-Apr-03 6:45 
AnswerRe: CreateProcess ??? Pin
valikac14-Apr-03 7:41
valikac14-Apr-03 7:41 
GeneralI can´t understand why it doesn´t work Pin
Martin_Viet14-Apr-03 5:24
Martin_Viet14-Apr-03 5:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.