Skip to content
Snippets Groups Projects
Commit 92ff9880 authored by Nadav Har'El's avatar Nadav Har'El
Browse files

Drasticly lower overhead of leak detection on running program

Leak detection (e.g., by running with "--leak") used to have a devastating
effect on the performance of the checked program, which although was
tolerable (for leak detection, long runs are often unnecessary), it was
still annoying.

While before this patch leak-detection runs were roughly 5 times slower
than regular runs, after this patch they are only about 40% slower than
a regular run! Read on for the details.

The main reason for this slowness was a simplistic vector which was used to
keep the records for currently living allocations. This vector was linearly
searched both for free spots (to remember new allocations) and for specific
addresses (to forget freed allocations). Because this list often grew to a
hundred thousand of items, it became incredibly slow and slowed down the
whole program. For example, getting a prompt from cli.jar happened in 2
seconds without leak detection, but in 9 seconds with leak detection.

A possible solution would have been to use an O(1) data structure, such as
a hash table. This would be complicated by our desire to avoid frequent
memory allocation inside the leak detector, or our general desire to avoid
complicated stuff in the leak detector because they always end leading to
complicated deadlocks :-)

This patch uses a different approach, inspired by an idea by Guy.

It still uses an ordinary vector for holding the records, but additionally
keeps for each record one "next" pointer which is used for maintaining two
separate lists of records:

1. A list of free records. This allows a finding a record for a new
   allocation in O(1) time.

2. A list of filled records, starting with the most-recently-filled record.
   When we free(), we walk this list and very often finish very quickly,
   because malloc() closely followed by free() are very common.
   Without this list, we had to walk the whole vector filled with ancient
   allocations and even free records, just to find the most recent
   allocation.

Two examples of the performance with and without this patch:

1. Getting a prompt from cli.jar takes 2 seconds without leak detection,
   9 seconds with leak detection before this patch, and 3 seconds with this
   patch.

2. The "sunflow" benchmark runs 53 ops/second without leak detection,
   which went down to 10 ops/second with leak detection before this patch,
   and after this patch - 33 ops/second.

I verified (by commenting out the search algorithm and always using the
first item in the vector) that the allocation record search is no longer
having any effect on performance, so it is no longer interesting to replace
this code with an even more efficient hash table. The remaining slowdown is
probably due to the backtrace() operation and perhaps also the tracker lock.
parent 8ffe45bf
No related branches found
No related tags found
No related merge requests found
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment