views:

281

answers:

7

For the past few months I've been working on a Visual C++ project to take images from cameras and process them. Up until today this has taken about 65 ms to update the data but now it has suddenly increased significantly. What happens is: I launch my program and for the first 30 or so iterations it performs as expected, then suddenly the loop time increases from 65 ms to 250 ms.

The odd thing is, after timing each function I found out that the part of the code which is causing the slowdown is fairly basic and has not been modified in over a month. The data which goes into it is unchanged and identical every iteration but the execution time which is initially less than 1 ms suddenly increases to 170 ms while the rest of the code is still performing as expected (time-wise).

Basically, I am calling the same function over and over, for the first 30 calls it performs as it should, after that it slows down for no apparent reason. It might also be worth noting that it is a sudden change in execution time, not a gradual increase.

What could be causing this? The code is leaking some memory (~50 kb/s) but not nearly enough to warrant a sudden 4x slowdown. If anyone has any ideas I'd love to hear them!

Edit: Wow, that was fast! Here's the code (minus some maths) which slows down. I know this is a function where the computational time will increase rapidly if you increase the number of lines. The key here is that with the same data this slows down after 30 iterations.

void CameraManager::IntersectLines()
{

    // Two custom classes
    TMaths maths;
    TLine line1, line2;

    while(lines.size()>0)
    {

        // Save the current line
        line1 = lines[0];

        // Then remove it from the list
        lines.erase(lines.begin());

        CvMat* aPoint;
        for (int i = 0; i<lines.size(); i++)
        {

            line2 = lines[i];

            aPoint = cvCreateMat(1, 4, CV_32FC1);

            // Calculate the point of intersection
            maths.Intersect(line1.xyz, line2.xyz, line1.uvw, line2.uvw, aPoint);

            // Add the point to the list
            points.push_back(aPoint);
            }

        }

    }

}

+9  A: 

Is it possible that after leaking a certain amount of memory, your computer has to start paging stuff in/out? That would definitely slow down even simple functions.

Without knowing what the function does, it's hard to say exactly what could be causing the problem.

Edit: As suggested in question comments, leaking a certain amount of memory could also start knocking things out of the CPU cache, which will also slow things down. Either fixing the memory leak, or posting the code here for us to look at, would be a good idea.

Edit 2: You call a couple of functions in that loop. Do they do anything other than simple arithmetic calculations?

Colen
Beat me by a second!
mcandre
Yeah, I was thinking paging too, the thing is that the program uses about 40 mb of ram (+50kb/s) with over 3.5 GB free so paging is likely not the issue.
Mikael
Not true. You've likely run into memory fragmentation problems. See my comment above to the initial question. The OS heap manager has to get the memory you're trying to allocate from somewhere, and that takes time. If you're fragmenting the heap, this will definitely slow down memory allocation. Search for "Low-fragmentation heap" for Windows.
Coleman
From the MSDN: "Applications that benefit most from the LFH are multi-threaded applications that allocate memory frequently and use a variety of allocation sizes under 16 KB. However, not all applications benefit from the LFH. To assess the effects of enabling the LFH in your application, use performance profiling data."
Coleman
@Coleman: Fragmentation, when you're using only 40MB? Doubtful
jalf
My read of his comment is that he's allocating 50kb/s, so fragmentation is possible in that circumstance.
Coleman
+5  A: 

If it leaks enough memory to fill up a page (50KB/s may be enough), then Windows will have to switch pages to handle the data. When this happens, the program becomes much more inefficient.

mcandre
A: 

You need to make your question a lot more specific if you want any useful answers.

This should really be written as a comment, not an answer.
Jerry Coffin
@Jerry, you need a rep of 50 to leave a comment. Kind of unfortunate, I think.
Mark Ransom
@Mark: Ah, I hadn't noticed that. I agree it's unfortunate, but I guess it's a question for meta, not here...
Jerry Coffin
+2  A: 

Obviously something has changed. Try reverting your code to what it was before the slow down. If it then is fast again, focus on the code changes. If it is slow, then look for the problem outside of your code. Things like the database, the OS, etc.

aaaa bbbb
+2  A: 

If you've got a memory leak, there's definitely something bad happening in your code. Fix that first and chances are you'll discover your problem or at least eliminate one fairly obvious suspect.

As others have mentioned, it would be much easier to try and help you if you provided some code...

[Edit] I'd guess that your cvCreateMat function allocates some memory? Does that ever get freed anywhere?

Jon Cage
+1  A: 

Do you need to erase each line in the container?

    // Then remove it from the list
    lines.erase(lines.begin());

Depending on the container, erasing elements (one at a time) may be slow especially for large containers. I suggest using a starting index during the computation. Advance the index before calling the function. Indexes and iterators are quicker to update than erasing an element. After the computation, you can remove or erase the entire container (see the clear method if the container has one). The clear method may be faster than erasing one element at a time.

Thomas Matthews
Thanks, now it lasts about 60 iterations before bailing out :) It's a good start.
Mikael
+1  A: 

Profile the code, then you won't need to guess at answers.

Of course, this may change the performance of the code anyway, but it's the most direct method of seeing exactly what is going on with your code...

(According to the current top answer to this question : http://stackoverflow.com/questions/61669/profiling-in-visual-studio-2008-pro you need the "Team" edition of VS 2008 to use the built-in profiler, otherwise you'll need to use an external profiler)

Legooolas