From: GrayFox on
Thanks for your reaction!
Well that's the strange thing about this all: The thread I start isn't
really doing anything with the GUI at all. It's just nicely doing it's
calculations on its own, minding its own business, unless I'm horribly
missing something here.

All that I do have is a timer set to 1 sec, and on the OnTimer() event I
read the counter that is being incremented by the worker thread every loop
and put it back to 0 again.
I then put the value I've read onto a static text object on the GUI. But
this is all happening only once a second.

Also, I forgot to mention, after the lps has dropped, it goes back up to
30-35 again as well after a while. I've used Process Explorer, and I do think
I see a slight increase in CPU usage when the lps drop, but mainly stuff like
svchost and opera using some CPU time, not much more.

Here is some code:

DWORD WINAPI Thread(LPVOID pParam) {
CMyDlg * pMyDlg;
pMyDlg = (CMyDlg *) pParam;
return pMyDlg->MainLoopFunc();
}


BOOL CMyDlg::OnInitDialog() {
HANDLE hThread = CreateThread(NULL, 0,
Thread, this, 0, NULL);
SetTimer(1, 1000, 0);
}

void CAmbloneDlg::OnTimer(UINT_PTR nIDEvent) {
CString Text;
Text.Format("Loops per second: %d lps", loopc);
StaticLoops.SetWindowTextA(Text);
loopc = 0;

CDialog::OnTimer(nIDEvent);
}

And this is the main function:

UINT CAmbloneDlg::MainLoopFunc() {

//--------------------------------------------
// Get some information about the screen etc.
// -------------------------------------------

ZeroMemory(&dd, sizeof(dd));
dd.cb = sizeof(dd);

do {
if (EnumDisplayDevices(NULL, settings.GetDisplayDeviceNum(), &dd, NULL)) {
// We found the monitor, now get the screen DC
hScrDC = CreateDC(NULL,dd.DeviceName,NULL,NULL);

// Get the screen resolution
xScrn = GetDeviceCaps(hScrDC, HORZRES);
yScrn = GetDeviceCaps(hScrDC, VERTRES);

// Create a bitmap compatible with the screen DC
hBitmap = CreateCompatibleBitmap(hScrDC, xScrn, yScrn);

// Create a memory DC compatible to screen DC
hMemDC = CreateCompatibleDC(hScrDC);

// Create a rectangle
GetClientRect(&rect);

pDC = GetDC(); // Get the DC

do {
// ----------------------
// This is the main loop
// ----------------------

// Calculate the average screen pixel colour
GetAverageRGB();

// Now output the colour
OutputColour();

if (counting) loopc++;

} while (KeepRunning);
}
DeleteDC(hScrDC);
DeleteDC(hMemDC);

} while (restart);
return 0;
}
From: Hector Santos on
Without knowing what the main loop is doing, including if it breaks
outs and does the restart loop again, if you see this loop

do {
GetAverageRGB();
OutputColour();
if (counting) loopc++;
} while (KeepRunning);

is showing a 30 lps, that means the two functions is using up 33 ms of
CPU time in each loop. If lps goes down to 10 lps, then the two
functions are using more cpu time - 100 ms in each loop.

So whatever is going on in those two functions.... :)

If I replace those two functions with:

Sleep(30);

I will see the 30 lps as well. if I change it to:

Sleep(100);

I see the 10 lps.

So that just to use how much time the two functions are using. You
need to figure out why. :)

Let us know.

--



GrayFox wrote:

> Thanks for your reaction!
> Well that's the strange thing about this all: The thread I start isn't
> really doing anything with the GUI at all. It's just nicely doing it's
> calculations on its own, minding its own business, unless I'm horribly
> missing something here.
>
> All that I do have is a timer set to 1 sec, and on the OnTimer() event I
> read the counter that is being incremented by the worker thread every loop
> and put it back to 0 again.
> I then put the value I've read onto a static text object on the GUI. But
> this is all happening only once a second.
>
> Also, I forgot to mention, after the lps has dropped, it goes back up to
> 30-35 again as well after a while. I've used Process Explorer, and I do think
> I see a slight increase in CPU usage when the lps drop, but mainly stuff like
> svchost and opera using some CPU time, not much more.
>
> Here is some code:
>
> DWORD WINAPI Thread(LPVOID pParam) {
> CMyDlg * pMyDlg;
> pMyDlg = (CMyDlg *) pParam;
> return pMyDlg->MainLoopFunc();
> }
>
>
> BOOL CMyDlg::OnInitDialog() {
> HANDLE hThread = CreateThread(NULL, 0,
> Thread, this, 0, NULL);
> SetTimer(1, 1000, 0);
> }
>
> void CAmbloneDlg::OnTimer(UINT_PTR nIDEvent) {
> CString Text;
> Text.Format("Loops per second: %d lps", loopc);
> StaticLoops.SetWindowTextA(Text);
> loopc = 0;
>
> CDialog::OnTimer(nIDEvent);
> }
>
> And this is the main function:
>
> UINT CAmbloneDlg::MainLoopFunc() {
>
> //--------------------------------------------
> // Get some information about the screen etc.
> // -------------------------------------------
>
> ZeroMemory(&dd, sizeof(dd));
> dd.cb = sizeof(dd);
>
> do {
> if (EnumDisplayDevices(NULL, settings.GetDisplayDeviceNum(), &dd, NULL)) {
> // We found the monitor, now get the screen DC
> hScrDC = CreateDC(NULL,dd.DeviceName,NULL,NULL);
>
> // Get the screen resolution
> xScrn = GetDeviceCaps(hScrDC, HORZRES);
> yScrn = GetDeviceCaps(hScrDC, VERTRES);
>
> // Create a bitmap compatible with the screen DC
> hBitmap = CreateCompatibleBitmap(hScrDC, xScrn, yScrn);
>
> // Create a memory DC compatible to screen DC
> hMemDC = CreateCompatibleDC(hScrDC);
>
> // Create a rectangle
> GetClientRect(&rect);
>
> pDC = GetDC(); // Get the DC
>
> do {
> // ----------------------
> // This is the main loop
> // ----------------------
>
> // Calculate the average screen pixel colour
> GetAverageRGB();
>
> // Now output the colour
> OutputColour();
>
> if (counting) loopc++;
>
> } while (KeepRunning);
> }
> DeleteDC(hScrDC);
> DeleteDC(hMemDC);
>
> } while (restart);
> return 0;
> }



--
HLS
From: Joseph M. Newcomer on
How are you copying get? GetPixel()? That is certainly the wrong way to go about it, if
that is what you are doing. You would want to create a DC and capture the bitmap (as I
described in my essay on capturing windows), but be aware that you are consuming GDI
resources, and if you consume too many, you will eventually hit problems. Since you have
not actually described the algorithm in any detail, or shown any code, there is no way to
tell what is going wrong from this description, so I've just made a few guesses as to what
might be happening.
joe

On Wed, 31 Mar 2010 15:30:42 -0700, GrayFox <GrayFox(a)discussions.microsoft.com> wrote:

>I'm writing a program that copies the bitmap of the desktop (like a
>screenshot), calculates the average RGB value of the screen, and send it over
>USB.
>Everything is working and I manage to get 30+ loops per second, which is
>good enough.
>
>However, after some time (varying between ~20 sec and ~1 min 30 sec), and
>not doing anything else, the loops per second suddenly drop to about 10 loops
>per second, which is too slow for my purpose. This transition happens within
>a fraction of a second.
>
>When I watch the Task Manager, and don't see anything special happening. The
>CPU time for my process remains the same, the total CPU usage is quite
>stable, memory usage is stable as well.
>
>I've tried changing Thread priority and Process priority but nothing seems
>to work. I am at a loss here.
>
>Anyone has any ideas? I would greatly appreciate any suggestions, advice and
>thoughts.
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Joseph M. Newcomer on
See below...
On Thu, 1 Apr 2010 03:26:01 -0700, GrayFox <GrayFox(a)discussions.microsoft.com> wrote:

>
>
>"Hector Santos" wrote:
>
>> How are you doing these "loops?" In a Thread? in a MFC OnTimer?
>>
>> You might have to do this in a background thread.
>
>
>I'm creating a thread from the initial dialog. So I just have a dialog based
>application, and then on the OnInitDialog() I call CreateThread(), and as an
>argument, I pass the 'this' pointer, so the thread (a global function) can
>start a member function of the dialog class. I set the priority to
>THREAD_PRIORITY_HIGHEST
****
Call AfxBeginThread. CreateThread is erroneous. It does not ensure the C runtime or the
MFC runtime multithread support are properly initialized.
joe

>
>
>"Woody" wrote:
>
>> Your symptom suggests a switch from RAM to paged memory, which could
>> occur if you are creating objects from heap memory ('new') but not
>> deleting them. Also, if you're using XP, be sure you have SP 3, as
>> there was a resource leak in SP 2.
>>
>> To see what's happening, you might want to use Process Explorer
>> (download from SysInternals). If you do use Task Manager, be sure you
>> have all the columns selected. Then, you can compare fast operation to
>> slow operation, and see if there's anything obvious.
>> .
>>
>
>I am running Vista, so that can't be it. Besides, I've already created
>nearly all variables as members of the class, and not allocating them in
>every loop cycle, mainly to avoid cpu time for the allocation and to prevent
>memory leaks.
>You're RAM to paging theory sounds pretty interesting, I'll check that out.
>I'll try Process Explorer as you advised.
>Thanks already guys!
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Hector Santos on
Joe,

He has a thread loop:

do {
GetAverageRGB()
OutputColor()
} while (KeepRunning);

which is where it slows down and picks up again.

Joseph M. Newcomer wrote:

> How are you copying get? GetPixel()? That is certainly the wrong way to go about it, if
> that is what you are doing. You would want to create a DC and capture the bitmap (as I
> described in my essay on capturing windows), but be aware that you are consuming GDI
> resources, and if you consume too many, you will eventually hit problems. Since you have
> not actually described the algorithm in any detail, or shown any code, there is no way to
> tell what is going wrong from this description, so I've just made a few guesses as to what
> might be happening.
> joe
>
> On Wed, 31 Mar 2010 15:30:42 -0700, GrayFox <GrayFox(a)discussions.microsoft.com> wrote:
>
>> I'm writing a program that copies the bitmap of the desktop (like a
>> screenshot), calculates the average RGB value of the screen, and send it over
>> USB.
>> Everything is working and I manage to get 30+ loops per second, which is
>> good enough.
>>
>> However, after some time (varying between ~20 sec and ~1 min 30 sec), and
>> not doing anything else, the loops per second suddenly drop to about 10 loops
>> per second, which is too slow for my purpose. This transition happens within
>> a fraction of a second.
>>
>> When I watch the Task Manager, and don't see anything special happening. The
>> CPU time for my process remains the same, the total CPU usage is quite
>> stable, memory usage is stable as well.
>>
>> I've tried changing Thread priority and Process priority but nothing seems
>> to work. I am at a loss here.
>>
>> Anyone has any ideas? I would greatly appreciate any suggestions, advice and
>> thoughts.
> Joseph M. Newcomer [MVP]
> email: newcomer(a)flounder.com
> Web: http://www.flounder.com
> MVP Tips: http://www.flounder.com/mvp_tips.htm



--
HLS