From: GrayFox on 31 Mar 2010 18:30 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.
From: Hector Santos on 31 Mar 2010 18:47 How are you doing these "loops?" In a Thread? in a MFC OnTimer? You might have to do this in a background thread. -- GrayFox 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. -- HLS
From: Woody on 1 Apr 2010 03:57 On Mar 31, 3:30 pm, GrayFox <Gray...(a)discussions.microsoft.com> wrote: > 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. 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.
From: GrayFox on 1 Apr 2010 06:26 "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 "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!
From: Hector Santos on 1 Apr 2010 07:41 GrayFox 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 First, I would personally put aside the thread priority increase until all the "logic" is worked out, then if you need higher priority, play with it. Its hard to imagine what exactly the type of work you are doing and how or rather what effect you have when communicating with the main (GUI) thread. Are you writing results back via This->DialogFunction(data)? As long as you are not using multiple threads to write to the same resource, it should work fine. You indicated 30 loops per second which is ok for you? What I did was create a quick MFC dialog with: - Start Thread Button IDC_BTN_STARTTHREAD - Stop Thread Button IDC_BTN_STOPTHREAD - ListBox IDC_LIST_LOG, change property Sort to FALSE - Add Variable CListBox mc_log for dlg class - Add Variable HANDLE hThread (initial to NULL in constructor) - Add Variable BOOL bAbort (initial to FALSE in constructor) Then create this thread proc: DWORD CALLBACK ClientThread(void *p) { CTestMfcThreadGreyFoxDlg *dlg = (CTestMfcThreadGreyFoxDlg *)p; dlg->mc_log.AddString(L"- Starting Thread"); while (!dlg->bAbort) { Sleep(1000/33); // about 30 loops per sec dlg->mc_log.AddString(L"- Tick"); } dlg->mc_log.AddString(L"- Ending Thread"); return 0; } and the Start Button Click function: void CTestMfcThreadGreyFoxDlg::OnBnClickedBtnStartthread() { GetDlgItem(IDC_BTN_STARTTHREAD)->EnableWindow(FALSE); GetDlgItem(IDC_BTN_STOPTHREAD)->EnableWindow(TRUE); DWORD tid; if (hThread == NULL) { bAbort = FALSE; hThread = CreateThread(NULL, 0, ClientThread, this, 0, &tid); } } and the Stop Button Click function: void CTestMfcThreadGreyFoxDlg::OnBnClickedBtnStopthread() { if (hThread != NULL) { bAbort = TRUE; while (1) { DWORD rc = WaitForSingleObject(hThread,25); if (rc == WAIT_OBJECT_0) { CloseHandle(hThread); hThread = NULL; GetDlgItem(IDC_BTN_STARTTHREAD)->EnableWindow(TRUE); GetDlgItem(IDC_BTN_STOPTHREAD)->EnableWindow(FALSE); mc_log.AddString(L"* Thread Ended"); break; } if (rc == WAIT_OBJECT_0) { mc_log.AddString(L"* Waiting for Thread to end"); } // process any messages MSG msg; if ( PeekMessage(&msg, this->m_hWnd, 0, 0, PM_REMOVE) ) { TranslateMessage(&msg); DispatchMessage(&msg); } } } } And it all seem fine to me, even after 45 minute when I went to have breakfast. :) If your loops is slowing down, then I can only imaging the its getting slowed down with the dialog function call from the thread. In other words, the function is slowing down. Technically the thread is blocked when it makes the call until the dlg function is complete. For example, in this code where the thread called: dlg->mc_log.AddString(L"- Tick"); Eventually after a long time, that could slow down because the log will be be big. If it was in SORT mode, that will even slow it down further. It could be, forever you are doing, that you could be generating a lot of messages. Generally, the alternative and often better way is to post a message to the main thread, that way your thread will not be blocked. But as dialog function is fast and not doing a lot of work, it shouldn't be a problem. You indicated 30 loops per second, that is about 33 milliseconds per loop. A quantum is 15 msecs so your loop will be preempted at least twice. Not sure how that will play a role without looking at whats being down. Increasing the priority may even preempt more times to give your thread more time. That may all depend on what other threads have the same priority. So that is why you want to work out the logic first before you do this. Short of looking at your code, this the best I can tell ya. Maybe others can provide some insight. -- HLS
|
Next
|
Last
Pages: 1 2 3 Prev: MFC app - add multithreading? Next: Struggling to get large application icon on Vista |