Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Application slow, page fault delta high, tried VirtualLock (C / VS / Win7)

Posted on 2011-05-10
9
Medium Priority
?
1,487 Views
Last Modified: 2012-05-11
Hello,

I have a problem with an video processing application that I've developed in C using Visual Studio. On complex images (resulting in more matrix operations), it runs extremely slow (less than 0.5 FPS compared to 30+ FPS in a marginally simpler case).

Using ProcessExplorer I have pinpointed the problem to page faults. For a simple image (camera against the wall eg.), page fault delta is about 30 000 - 50 000 (which I guess is abnormally high). As the camera is moved to a more complex scene, page fault delta approaches 80 000 +, where the application suddenly slows down almost to a stop.

The algorithm uses several large matrices for its operations, so my guess is these are located in virtual memory, resulting in the high number of page faults. My question is, why are these kept in the virtual memory even after they are accessed, and is there a way I can force them to physical memory?

I have tried using the VirtualLock function on the relevant matrices. Although the function returned success, there is no noticeable improvement in performance, and page fault delta stays high.

Code:

Matrices are global and statically allocated, as follows:

 
#define SEGMENT_LIMIT 30

typedef struct
{
	int x;
	int y;
} pos;

typedef pos pos_array[SEGMENT_LIMIT][640*480];

////

pos stack[640*480];
char visited_array[480][640];
char added_array[480][640];
pos_array segment_array;

Open in new window


The code where I attempt to lock them to physical memory:

 
DWORD pid = GetCurrentProcessId();

HANDLE hProcess = OpenProcess(PROCESS_SET_QUOTA, FALSE, pid);

if (hProcess == NULL)
    return false;

BOOL result = SetProcessWorkingSetSize(hProcess, 400*1000*1000, 400*1000*1000);

CloseHandle(hProcess);

if ( ! result)
    return false;

if(!VirtualLock(stack, sizeof(stack)))
    return false;

if(!VirtualLock(visited_array, 640*480))
    return false;

if(!VirtualLock(added_array, 640*480))
    return false;

if(!VirtualLock(segment_array, sizeof(pos)*640*480*SEGMENT_LIMIT))
    return false;

return true;

Open in new window

0
Comment
Question by:Fortythreee
9 Comments
 
LVL 14

Expert Comment

by:sentner
ID: 35730491
If your application is working from swap, it's because you are allocating more memory than the system has available in physical RAM.  Your best bet is to ensure that you are efficiently using memory, re-using arrays where possible so you don't have to re-allocate, and freeing up blocks that you are done with.

I can tell you that the amount of memory you're allocating is very large.  Without seeing how you are creating and destroying the memory handles though, I can't tell how much you're program is actually using at any time.   Every instance of the pos_array type is going to allocate 72MB of RAM.

Can you paste some of the code where you are actually creating the variables that use the large memory blocks, and how you are freeing them up?

0
 

Author Comment

by:Fortythreee
ID: 35735577
Thanks for your reply.

The static allocations posted in my earlier post are the only variables used in the algorithm, and they are never freed, as the same static matrices are used at each run. So total memory use should be less than 100 MB, and is the same throughout an entire execution of the application. Also, the machine has about 3 GB free physical memory while I am running the application.

I can post more of the relevant code later when I'm at my working computer.
0
 
LVL 4

Expert Comment

by:fromer
ID: 35736185
72 megabyte of consecutive bytes...
I think the problem is here...

Can you change this to a VectorList or someother list so that it's not consecutive?
typedef pos pos_array[SEGMENT_LIMIT][640*480];
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:Fortythreee
ID: 35737333
Can you describe the problem for me, so that I know how to fix it? Do you suggest I use a dynamic data type? I am using arrays for performance. Is there a way I can change my array so that it is not consecutive, and how would that solve the problem? Thanks a lot
0
 
LVL 7

Expert Comment

by:huacat
ID: 35738920
I would like to create a simple deom program allocte memory of
typedef pos pos_array[SEGMENT_LIMIT][640*480];
and use for statement to scan all elements to test if the page fault is high.
var
  pos_array: array[1..30, 1..640*480] of TPoint;

procedure TForm1.Button1Click(Sender: TObject);
var
  i : Integer;
  j : Integer;
begin
  for i := 1 to 30 do
    for j := 1 to 640 * 480 do
    begin
      pos_array[i][j].X := Random(640);
      pos_array[i][i].Y := Random(480);
    end;
end;

Open in new window

I create a demo program, and the first time to scan the pos_array cause hight page fault(about 19200), after the first visit, no matter what it is how many time I scan the pos_array, the page fault almost not increase!

But when I mimize the program, and scan the pos_array again, the page fault increased as the first run. When minimize the program, OS will empty the workset of the program.

I would like to split source codes to some segments, and found which segment cause the high page fault.
0
 
LVL 7

Expert Comment

by:huacat
ID: 35739086
I using VirtualLock to lock the pos_array, and found the page fault not increased even I mimized the program. It works fine for the demo code:
 
var
  pos_array: array[1..30, 1..640*480] of TPoint;

procedure TForm1.btn1Click(Sender: TObject);
var
  i : Integer;
  j : Integer;
begin
  for i := 1 to 30 do
    for j := 1 to 640 * 480 do
    begin
      pos_array[i][j].X := Random(640);
      pos_array[i][i].Y := Random(480);
    end;
end;

procedure TForm1.btn2Click(Sender: TObject);
var
  pid : Thandle;
  process: THandle;
begin
  pid := GetCurrentProcessId;
  process := OpenProcess(PROCESS_SET_QUOTA, FALSE, pid);
  if not SetProcessWorkingSetSize(Process, 400*1000*1000, 400*1000*1000) then Beep;
  VirtualLock(@pos_array[1][1], SizeOf(pos_array));
  Caption := SysErrorMessage(GetLastError);
end;

Open in new window

0
 

Accepted Solution

by:
Fortythreee earned 0 total points
ID: 35744399
Thank you for your replies, with more testing I believe that the page fault is not the reason for the application being slow. In some cases I have 90k+ PFD with no decrease in performance. Therefore I will not spend more time on solving the PF problem. I will instead investigate in multi-threading my algorithm.
0
 

Author Comment

by:Fortythreee
ID: 35744915
Retracting my earlier comment - increased processor load only decreases performance linearly in my application, whereas my problem arrives suddenly..

I tried making a test application which uses the same data structures and about the same instructions - zero page faults, even while minimizing.

Can it be related to threading? This thread is mutexed with the thread for presenting data graphically. Will test with no thread locks.
0
 

Author Closing Comment

by:Fortythreee
ID: 35775361
Problem solved, PF delta was related to graphics, slow performance related to a high complexity loop.
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

IF you are either unfamiliar with rootkits, or want to know more about them, read on ....
A few solutions to a problem some of us have been having when trying to add Hostgator email accounts to Outlook 2016 (will probably work with Outlook 2013 as well).
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.
This is used to tweak the memory usage for your computer, it is used for servers more so than workstations but just be careful editing registry settings as it may cause irreversible results. I hold no responsibility for anything you do to the regist…

572 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question