Skip to content

Threshold issue for flint_mpn_sqr on raptorlake-pc-linux-gnu #2873

Closed

Description

@maelhos

Describe the bug
The cutoff for flint_mpn_sqr seem to use the wrong algorithm around 42k limbs on my system.

Steps to reproduce
Here is a minimal example :

/* flint_mpn_sqr throughput dip around 42k-48k limbs */
#include <stdio.h>
#include <time.h>
#include <gmp.h>
#include <flint/flint.h>
#include <flint/mpn_extras.h>

static double secs(void) { struct timespec t; clock_gettime(CLOCK_MONOTONIC, &t); return t.tv_sec + 1e-9 * t.tv_nsec; }

int main(void)
{
    static ulong a[60000], r[120000];
    for (slong i = 0; i < 60000; i++) a[i] = 0x9E3779B97F4A7C15UL * (i + 1);
    printf("%8s %14s %14s\n", "limbs", "flint ns/limb", "gmp ns/limb");
    for (slong n = 36000; n <= 54000; n += 2000)
    {
        double t0 = secs(); for (int k = 0; k < 20; k++) flint_mpn_sqr(r, a, n);
        double t1 = secs(); for (int k = 0; k < 20; k++) mpn_sqr(r, a, n);
        double t2 = secs();
        printf("%8ld %14.1f %14.1f\n", n, (t1 - t0) / 20 / n * 1e9, (t2 - t1) / 20 / n * 1e9);
    }
    return 0;
}
   limbs  flint ns/limb    gmp ns/limb
   36000           52.5          118.4
   38000           44.1          115.7
   40000           43.8          127.1
   42000          166.9          122.5
   44000          166.2          112.9
   46000          165.9          108.7
   48000          165.2          101.5
   50000           50.8          127.2
   52000           50.3          125.1
   54000           50.0          119.0

Expected behavior
From 42k to 48k limbs, we should also expect around 50 ns/limbs...

System (please complete the following information):
Using latest commit of the git main branch on
13th Gen Intel Core i7-13850HX, AVX2, no AVX-512
Linux 7.0.0-38-generic, gcc 15.2.0, GMP 6.3.0
FLINT 3.7.0-dev @ abb92f3, with FLINT_HAVE_FFT_SMALL 1
FLINT_FFT_SMALL_MUL_THRESHOLD and FLINT_FFT_SMALL_SQR_THRESHOLD are both 500

architecture recognized as raptorlake-pc-linux-gnu

Activity

  1. vneiger commented on Oct 7, 2026

    @vneiger
    Collaborator

    Many parameters for Raptor Lake are copied directly from values determined for skylake, which can be quite off. See the comments in
    https://github.com/flintlib/flint/blob/main/src/mpn_extras/x86_64/raptorlake/flint-mparam.h

    If you do measurements that allow you to improve these thresholds (all of the wrong ones, or some of them), feel free to open a PR that improves this raptorlake/flint-mparam file! Putting the same values in other files from CPUs similar to RaptorLake (instead of Skylake values that are likely to be less relevant) could be good too.

    Ideally, at some point, we would have some easy way to determine good values for most of the thresholds in these flint-mparam files (at least those that don't require to run several hours of benchmarks). Currently, you should locate the right profile files (possibly create some profile files), and do things by hand for every value.

  2. vneiger commented on Oct 7, 2026

    @vneiger
    Collaborator

    (My previous message is assuming that the issue only comes from wrongly tuned thresholds in flint-mparam, but it is maybe more complicated than this?)

  3. maelhos commented on Oct 7, 2026

    @maelhos
    ContributorAuthor

    Many parameters for Raptor Lake are copied directly from values determined for skylake, which can be quite off. See the comments in https://github.com/flintlib/flint/blob/main/src/mpn_extras/x86_64/raptorlake/flint-mparam.h

    If you do measurements that allow you to improve these thresholds (all of the wrong ones, or some of them), feel free to open a PR that improves this raptorlake/flint-mparam file! Putting the same values in other files from CPUs similar to RaptorLake (instead of Skylake values that are likely to be less relevant) could be good too.

    Can you test that this affect only my architecture ? (if you have time) How about zen 3/4/5 and true skylake with my small example ?

  4. fredrik-johansson commented on Oct 7, 2026

    @fredrik-johansson
    Collaborator

    On Zen 3:

       limbs  flint ns/limb    gmp ns/limb
       36000           41.8          102.7
       38000           40.0           98.3
       40000           39.5          105.2
       42000           51.8           95.9
       44000           50.1           89.1
       46000           50.3           86.1
       48000           49.7           80.5
       50000           46.5          100.5
       52000           46.4          100.5
       54000           46.0           95.8
    
  5. vneiger commented on Oct 7, 2026

    @vneiger
    Collaborator

    I guess zen4 will be similar to zen3. Here is on two servers, broadwell first and then cascade lake:

    limbs  flint ns/limb    gmp ns/limb
       36000          155.0          314.0
       38000          142.7          312.8
       40000          141.6          336.7
       42000          213.7          321.2
       44000          210.9          300.0
       46000          210.0          287.9
       48000          208.2          269.0
       50000          147.8          333.5
       52000          146.8          330.1
       54000          146.0          315.5
    
    
    limbs  flint ns/limb    gmp ns/limb
       36000           79.1          150.7
       38000           72.0          151.0
       40000           71.3          160.5
       42000          113.6          154.4
       44000          112.5          145.5
       46000          112.6          139.1
       48000          111.0          130.5
       50000           78.8          161.0
       52000           78.8          159.9
       54000           78.0          153.2
    
    
  6. maelhos commented on Oct 7, 2026

    @maelhos
    ContributorAuthor

    Ok, so apparently this has something to do with the number of primes in FFT_SMALL. Honestly, I don't know enough about it to tell why, but in the mpn_mul.c line 1300, replacing

    P->np = n_max(n_min(P->nthreads, 8), 4);

    by

    P->np = n_max(n_min(P->nthreads, 7), 4);

    Fixes the issue...

       limbs  flint ns/limb    gmp ns/limb
       36000           61.8          119.7
       38000           47.4          116.5
       40000           47.0          126.0
       42000           47.2          122.2
       44000           47.2          112.5
       46000           51.4          108.4
       48000           50.1          101.2
       50000           49.9          126.9
       52000           50.0          124.1
       54000           49.6          118.2
    
  7. fredrik-johansson commented on Oct 7, 2026

    @fredrik-johansson
    Collaborator

    I wonder if this is the same as #2693/#2692, the 8-prime CRT not having enough registers and spilling to memory. If that's the case, it's curious that Zen 3 doesn't suffer the same slowdown.

  8. albinahlback commented on Oct 7, 2026

    @albinahlback
    Collaborator

    It seems like it does slow down for Zen 3, just not as much.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions