Skip to content

Try harder to reclaim memory in fmpz_single - #2788

Merged
fredrik-johansson merged 1 commit into
flintlib:mainfrom
fredrik-johansson:mpzclear
Aug 6, 2026
Merged

Try harder to reclaim memory in fmpz_single#2788
fredrik-johansson merged 1 commit into
flintlib:mainfrom
fredrik-johansson:mpzclear

Conversation

@fredrik-johansson

Copy link
Copy Markdown
Collaborator

The fmpz mpz cache is supposed to free slots with more than 64 limbs allocated, but does so with an mpz_realloc which isn't guaranteed to actually reclaim the memory.

This results in soft memory leaks for complex fmpz workloads with big coefficients where more and more coefficients get cached and the huge allocations stay in the pool. The memory can be reclaimed by calling flint_cleanup_master(), but this shouldn't be necessary.

The fix is to clear+init instead of realloc.

Demonstration:

#include "profiler.h"
#include "fmpz.h"
#include "fmpz_poly.h"

int main()
{
    flint_rand_t state;
    slong i, n, bits;

    flint_rand_init(state);

    fmpz_poly_t a, b, c;

    for (i = 0; i <= 200; i++)
    {
        n = 1 + n_randint(state, 1 + 1000 * (i % 10));
        bits = 1 + n_randint(state, 1 + 1000 * i);

        fmpz_poly_init(a);
        fmpz_poly_init(b);
        fmpz_poly_init(c);

        fmpz_poly_randtest(a, state, n, bits);
        fmpz_poly_randtest(b, state, n, bits);
        fmpz_poly_add(c, a, b);

        fmpz_poly_clear(a);
        fmpz_poly_clear(b);
        fmpz_poly_clear(c);

        if (i % 10 == 0)
            print_memory_usage();
    }

    flint_rand_clear(state);
    flint_cleanup_master();
    return 0;
}

Before (note the growing rss):

virt/peak/rss/peak: 19.5 MB / 19.5 MB / 2.61 MB / 2.61 MB
virt/peak/rss/peak: 26.8 MB / 26.8 MB / 12.0 MB / 12.0 MB
virt/peak/rss/peak: 32.9 MB / 32.9 MB / 17.9 MB / 17.9 MB
virt/peak/rss/peak: 54.7 MB / 54.7 MB / 39.8 MB / 39.8 MB
virt/peak/rss/peak: 54.9 MB / 54.9 MB / 40.1 MB / 40.1 MB
virt/peak/rss/peak: 60.8 MB / 60.9 MB / 46.1 MB / 46.1 MB
virt/peak/rss/peak: 74.6 MB / 74.6 MB / 59.8 MB / 59.8 MB
virt/peak/rss/peak: 75.9 MB / 76.0 MB / 61.2 MB / 61.2 MB
virt/peak/rss/peak:  102 MB /  103 MB / 87.8 MB / 87.8 MB
virt/peak/rss/peak:  102 MB /  103 MB / 87.7 MB / 87.8 MB
virt/peak/rss/peak:  106 MB /  106 MB / 91.6 MB / 91.6 MB
virt/peak/rss/peak:  117 MB /  117 MB /  102 MB /  102 MB
virt/peak/rss/peak:  212 MB /  212 MB /  197 MB /  197 MB
virt/peak/rss/peak:  212 MB /  212 MB /  197 MB /  197 MB
virt/peak/rss/peak:  212 MB /  212 MB /  197 MB /  197 MB
virt/peak/rss/peak:  212 MB /  212 MB /  197 MB /  197 MB
virt/peak/rss/peak:  212 MB /  212 MB /  197 MB /  197 MB
virt/peak/rss/peak:  212 MB /  212 MB /  197 MB /  197 MB
virt/peak/rss/peak:  212 MB /  212 MB /  197 MB /  197 MB
virt/peak/rss/peak:  212 MB /  212 MB /  197 MB /  197 MB
virt/peak/rss/peak:  212 MB /  212 MB /  197 MB /  197 MB

After:

virt/peak/rss/peak: 19.5 MB / 19.5 MB / 2.69 MB / 2.69 MB
virt/peak/rss/peak: 26.8 MB / 26.8 MB / 12.0 MB / 12.0 MB
virt/peak/rss/peak: 32.6 MB / 32.6 MB / 17.6 MB / 17.6 MB
virt/peak/rss/peak: 32.6 MB / 54.3 MB / 17.9 MB / 39.3 MB
virt/peak/rss/peak: 32.6 MB / 54.3 MB / 17.9 MB / 39.3 MB
virt/peak/rss/peak: 32.6 MB / 54.3 MB / 17.9 MB / 39.3 MB
virt/peak/rss/peak: 36.7 MB / 57.6 MB / 22.0 MB / 42.7 MB
virt/peak/rss/peak: 38.5 MB / 65.5 MB / 23.8 MB / 50.7 MB
virt/peak/rss/peak: 37.3 MB / 86.9 MB / 22.6 MB / 72.0 MB
virt/peak/rss/peak: 41.3 MB / 86.9 MB / 26.6 MB / 72.0 MB
virt/peak/rss/peak: 41.2 MB / 92.1 MB / 26.5 MB / 77.2 MB
virt/peak/rss/peak: 40.4 MB / 92.1 MB / 25.7 MB / 77.2 MB
virt/peak/rss/peak: 37.3 MB /  205 MB / 22.6 MB /  190 MB
virt/peak/rss/peak: 37.3 MB /  205 MB / 22.6 MB /  190 MB
virt/peak/rss/peak: 37.3 MB /  205 MB / 22.6 MB /  190 MB
virt/peak/rss/peak: 37.3 MB /  205 MB / 22.6 MB /  190 MB
virt/peak/rss/peak: 37.3 MB /  205 MB / 22.6 MB /  190 MB
virt/peak/rss/peak: 37.3 MB /  205 MB / 22.6 MB /  190 MB
virt/peak/rss/peak: 37.3 MB /  205 MB / 22.6 MB /  190 MB
virt/peak/rss/peak: 37.3 MB /  205 MB / 22.6 MB /  190 MB
virt/peak/rss/peak: 37.3 MB /  205 MB / 22.6 MB /  190 MB

@fredrik-johansson
fredrik-johansson merged commit 39787ef into flintlib:main Aug 6, 2026
12 checks passed
@fredrik-johansson
fredrik-johansson deleted the mpzclear branch August 6, 2026 22:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant