[v1] x86: Use 64MB as nt-store threshold if no cacheinfo [BZ #30429]

Message ID 20230509031020.3496291-1-goldstein.w.n@gmail.com
State Committed
Commit ed2f9dc9420c4c61436328778a70459d0a35556a
Headers
Series [v1] x86: Use 64MB as nt-store threshold if no cacheinfo [BZ #30429] |

Checks

Context Check Description
dj/TryBot-apply_patch success Patch applied to master at the time it was sent
dj/TryBot-32bit success Build for i686

Commit Message

Noah Goldstein May 9, 2023, 3:10 a.m. UTC
  If `non_temporal_threshold` is below `minimum_non_temporal_threshold`,
it almost certainly means we failed to read the systems cache info.

In this case, rather than defaulting the minimum correct value, we
should default to a value that gets at least reasonable
performance. 64MB is chosen conservatively to be at the very high
end. This should never cause non-temporal stores when, if we had read
cache info, we wouldn't have otherwise.
---
 sysdeps/x86/dl-cacheinfo.h | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)
  

Comments

Florian Weimer May 9, 2023, 8:56 a.m. UTC | #1
* Noah Goldstein via Libc-alpha:

> If `non_temporal_threshold` is below `minimum_non_temporal_threshold`,
> it almost certainly means we failed to read the systems cache info.
>
> In this case, rather than defaulting the minimum correct value, we
> should default to a value that gets at least reasonable
> performance. 64MB is chosen conservatively to be at the very high
> end. This should never cause non-temporal stores when, if we had read
> cache info, we wouldn't have otherwise.

I think that's quite surprising for GLIBC_TUNABLES.  Maybe that logic
should only activate if the default was set from cache sizes?

Thanks,
Florian
  
Noah Goldstein May 9, 2023, 4:01 p.m. UTC | #2
On Tue, May 9, 2023 at 3:56 AM Florian Weimer <fweimer@redhat.com> wrote:
>
> * Noah Goldstein via Libc-alpha:
>
> > If `non_temporal_threshold` is below `minimum_non_temporal_threshold`,
> > it almost certainly means we failed to read the systems cache info.
> >
> > In this case, rather than defaulting the minimum correct value, we
> > should default to a value that gets at least reasonable
> > performance. 64MB is chosen conservatively to be at the very high
> > end. This should never cause non-temporal stores when, if we had read
> > cache info, we wouldn't have otherwise.
>
> I think that's quite surprising for GLIBC_TUNABLES.  Maybe that logic
> should only activate if the default was set from cache sizes?
>
I don't quite understand what you mean by "only active if the default
was set from cache sizes"?

This logic only triggers if total_cachesize / 8 < ~16kb. I think this should
only ever really happen if we failed to read cache info. What is the
surprise?

> Thanks,
> Florian
>
  
Noah Goldstein May 11, 2023, 6:15 p.m. UTC | #3
On Tue, May 9, 2023 at 11:01 AM Noah Goldstein <goldstein.w.n@gmail.com> wrote:
>
> On Tue, May 9, 2023 at 3:56 AM Florian Weimer <fweimer@redhat.com> wrote:
> >
> > * Noah Goldstein via Libc-alpha:
> >
> > > If `non_temporal_threshold` is below `minimum_non_temporal_threshold`,
> > > it almost certainly means we failed to read the systems cache info.
> > >
> > > In this case, rather than defaulting the minimum correct value, we
> > > should default to a value that gets at least reasonable
> > > performance. 64MB is chosen conservatively to be at the very high
> > > end. This should never cause non-temporal stores when, if we had read
> > > cache info, we wouldn't have otherwise.
> >
> > I think that's quite surprising for GLIBC_TUNABLES.  Maybe that logic
> > should only activate if the default was set from cache sizes?
> >
> I don't quite understand what you mean by "only active if the default
> was set from cache sizes"?
>
> This logic only triggers if total_cachesize / 8 < ~16kb. I think this should
> only ever really happen if we failed to read cache info. What is the
> surprise?

florian?
>
> > Thanks,
> > Florian
> >
  
Florian Weimer May 25, 2023, 8:11 a.m. UTC | #4
* Noah Goldstein:

> On Tue, May 9, 2023 at 3:56 AM Florian Weimer <fweimer@redhat.com> wrote:
>>
>> * Noah Goldstein via Libc-alpha:
>>
>> > If `non_temporal_threshold` is below `minimum_non_temporal_threshold`,
>> > it almost certainly means we failed to read the systems cache info.
>> >
>> > In this case, rather than defaulting the minimum correct value, we
>> > should default to a value that gets at least reasonable
>> > performance. 64MB is chosen conservatively to be at the very high
>> > end. This should never cause non-temporal stores when, if we had read
>> > cache info, we wouldn't have otherwise.
>>
>> I think that's quite surprising for GLIBC_TUNABLES.  Maybe that logic
>> should only activate if the default was set from cache sizes?
>>
> I don't quite understand what you mean by "only active if the default
> was set from cache sizes"?
>
> This logic only triggers if total_cachesize / 8 < ~16kb. I think this should
> only ever really happen if we failed to read cache info. What is the
> surprise?

Right, my mistake.  The patch should work as-is.

Reviewed-by: Florian Weimer <fweimer@redhat.com>

Thanks,
Florian
  
H.J. Lu May 25, 2023, 6:36 p.m. UTC | #5
On Mon, May 8, 2023 at 8:10 PM Noah Goldstein <goldstein.w.n@gmail.com> wrote:
>
> If `non_temporal_threshold` is below `minimum_non_temporal_threshold`,
> it almost certainly means we failed to read the systems cache info.
>
> In this case, rather than defaulting the minimum correct value, we
> should default to a value that gets at least reasonable
> performance. 64MB is chosen conservatively to be at the very high
> end. This should never cause non-temporal stores when, if we had read
> cache info, we wouldn't have otherwise.
> ---
>  sysdeps/x86/dl-cacheinfo.h | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h
> index 864b00a521..6225c852f6 100644
> --- a/sysdeps/x86/dl-cacheinfo.h
> +++ b/sysdeps/x86/dl-cacheinfo.h
> @@ -771,8 +771,16 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
>       reflected in the manual.  */
>    unsigned long int maximum_non_temporal_threshold = SIZE_MAX >> 4;
>    unsigned long int minimum_non_temporal_threshold = 0x4040;
> +
> +  /* If `non_temporal_threshold` less than `minimum_non_temporal_threshold`
> +     it most likely means we failed to detect the cache info. We don't want
> +     to default to `minimum_non_temporal_threshold` as such a small value,
> +     while correct, has bad performance. We default to 64MB as reasonable
> +     default bound. 64MB is likely conservative in that most/all systems would
> +     choose a lower value so it should never forcing non-temporal stores when
> +     they otherwise wouldn't be used.  */
>    if (non_temporal_threshold < minimum_non_temporal_threshold)
> -    non_temporal_threshold = minimum_non_temporal_threshold;
> +    non_temporal_threshold = 64 * 1024 * 1024;
>    else if (non_temporal_threshold > maximum_non_temporal_threshold)
>      non_temporal_threshold = maximum_non_temporal_threshold;
>
> --
> 2.34.1
>

LGTM.

Thanks.
  
Noah Goldstein June 5, 2023, 5:14 p.m. UTC | #6
On Mon, May 8, 2023 at 10:10 PM Noah Goldstein <goldstein.w.n@gmail.com> wrote:
>
> If `non_temporal_threshold` is below `minimum_non_temporal_threshold`,
> it almost certainly means we failed to read the systems cache info.
>
> In this case, rather than defaulting the minimum correct value, we
> should default to a value that gets at least reasonable
> performance. 64MB is chosen conservatively to be at the very high
> end. This should never cause non-temporal stores when, if we had read
> cache info, we wouldn't have otherwise.
> ---
>  sysdeps/x86/dl-cacheinfo.h | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h
> index 864b00a521..6225c852f6 100644
> --- a/sysdeps/x86/dl-cacheinfo.h
> +++ b/sysdeps/x86/dl-cacheinfo.h
> @@ -771,8 +771,16 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
>       reflected in the manual.  */
>    unsigned long int maximum_non_temporal_threshold = SIZE_MAX >> 4;
>    unsigned long int minimum_non_temporal_threshold = 0x4040;
> +
> +  /* If `non_temporal_threshold` less than `minimum_non_temporal_threshold`
> +     it most likely means we failed to detect the cache info. We don't want
> +     to default to `minimum_non_temporal_threshold` as such a small value,
> +     while correct, has bad performance. We default to 64MB as reasonable
> +     default bound. 64MB is likely conservative in that most/all systems would
> +     choose a lower value so it should never forcing non-temporal stores when
> +     they otherwise wouldn't be used.  */
>    if (non_temporal_threshold < minimum_non_temporal_threshold)
> -    non_temporal_threshold = minimum_non_temporal_threshold;
> +    non_temporal_threshold = 64 * 1024 * 1024;
>    else if (non_temporal_threshold > maximum_non_temporal_threshold)
>      non_temporal_threshold = maximum_non_temporal_threshold;
>
> --
> 2.34.1
>

I want to backport down to 2.28.
Thoughts?
  
H.J. Lu June 5, 2023, 5:45 p.m. UTC | #7
On Mon, Jun 5, 2023 at 10:15 AM Noah Goldstein <goldstein.w.n@gmail.com> wrote:
>
> On Mon, May 8, 2023 at 10:10 PM Noah Goldstein <goldstein.w.n@gmail.com> wrote:
> >
> > If `non_temporal_threshold` is below `minimum_non_temporal_threshold`,
> > it almost certainly means we failed to read the systems cache info.
> >
> > In this case, rather than defaulting the minimum correct value, we
> > should default to a value that gets at least reasonable
> > performance. 64MB is chosen conservatively to be at the very high
> > end. This should never cause non-temporal stores when, if we had read
> > cache info, we wouldn't have otherwise.
> > ---
> >  sysdeps/x86/dl-cacheinfo.h | 10 +++++++++-
> >  1 file changed, 9 insertions(+), 1 deletion(-)
> >
> > diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h
> > index 864b00a521..6225c852f6 100644
> > --- a/sysdeps/x86/dl-cacheinfo.h
> > +++ b/sysdeps/x86/dl-cacheinfo.h
> > @@ -771,8 +771,16 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
> >       reflected in the manual.  */
> >    unsigned long int maximum_non_temporal_threshold = SIZE_MAX >> 4;
> >    unsigned long int minimum_non_temporal_threshold = 0x4040;
> > +
> > +  /* If `non_temporal_threshold` less than `minimum_non_temporal_threshold`
> > +     it most likely means we failed to detect the cache info. We don't want
> > +     to default to `minimum_non_temporal_threshold` as such a small value,
> > +     while correct, has bad performance. We default to 64MB as reasonable
> > +     default bound. 64MB is likely conservative in that most/all systems would
> > +     choose a lower value so it should never forcing non-temporal stores when
> > +     they otherwise wouldn't be used.  */
> >    if (non_temporal_threshold < minimum_non_temporal_threshold)
> > -    non_temporal_threshold = minimum_non_temporal_threshold;
> > +    non_temporal_threshold = 64 * 1024 * 1024;
> >    else if (non_temporal_threshold > maximum_non_temporal_threshold)
> >      non_temporal_threshold = maximum_non_temporal_threshold;
> >
> > --
> > 2.34.1
> >
>
> I want to backport down to 2.28.
> Thoughts?

Who will use such backport?
  
Noah Goldstein June 5, 2023, 8:28 p.m. UTC | #8
On Mon, Jun 5, 2023 at 12:46 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Mon, Jun 5, 2023 at 10:15 AM Noah Goldstein <goldstein.w.n@gmail.com> wrote:
> >
> > On Mon, May 8, 2023 at 10:10 PM Noah Goldstein <goldstein.w.n@gmail.com> wrote:
> > >
> > > If `non_temporal_threshold` is below `minimum_non_temporal_threshold`,
> > > it almost certainly means we failed to read the systems cache info.
> > >
> > > In this case, rather than defaulting the minimum correct value, we
> > > should default to a value that gets at least reasonable
> > > performance. 64MB is chosen conservatively to be at the very high
> > > end. This should never cause non-temporal stores when, if we had read
> > > cache info, we wouldn't have otherwise.
> > > ---
> > >  sysdeps/x86/dl-cacheinfo.h | 10 +++++++++-
> > >  1 file changed, 9 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h
> > > index 864b00a521..6225c852f6 100644
> > > --- a/sysdeps/x86/dl-cacheinfo.h
> > > +++ b/sysdeps/x86/dl-cacheinfo.h
> > > @@ -771,8 +771,16 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
> > >       reflected in the manual.  */
> > >    unsigned long int maximum_non_temporal_threshold = SIZE_MAX >> 4;
> > >    unsigned long int minimum_non_temporal_threshold = 0x4040;
> > > +
> > > +  /* If `non_temporal_threshold` less than `minimum_non_temporal_threshold`
> > > +     it most likely means we failed to detect the cache info. We don't want
> > > +     to default to `minimum_non_temporal_threshold` as such a small value,
> > > +     while correct, has bad performance. We default to 64MB as reasonable
> > > +     default bound. 64MB is likely conservative in that most/all systems would
> > > +     choose a lower value so it should never forcing non-temporal stores when
> > > +     they otherwise wouldn't be used.  */
> > >    if (non_temporal_threshold < minimum_non_temporal_threshold)
> > > -    non_temporal_threshold = minimum_non_temporal_threshold;
> > > +    non_temporal_threshold = 64 * 1024 * 1024;
> > >    else if (non_temporal_threshold > maximum_non_temporal_threshold)
> > >      non_temporal_threshold = maximum_non_temporal_threshold;
> > >
> > > --
> > > 2.34.1
> > >
> >
> > I want to backport down to 2.28.
> > Thoughts?
>
> Who will use such backport?

People using systems where we miscalculate cache size.
>
> --
> H.J.
  

Patch

diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h
index 864b00a521..6225c852f6 100644
--- a/sysdeps/x86/dl-cacheinfo.h
+++ b/sysdeps/x86/dl-cacheinfo.h
@@ -771,8 +771,16 @@  dl_init_cacheinfo (struct cpu_features *cpu_features)
      reflected in the manual.  */
   unsigned long int maximum_non_temporal_threshold = SIZE_MAX >> 4;
   unsigned long int minimum_non_temporal_threshold = 0x4040;
+
+  /* If `non_temporal_threshold` less than `minimum_non_temporal_threshold`
+     it most likely means we failed to detect the cache info. We don't want
+     to default to `minimum_non_temporal_threshold` as such a small value,
+     while correct, has bad performance. We default to 64MB as reasonable
+     default bound. 64MB is likely conservative in that most/all systems would
+     choose a lower value so it should never forcing non-temporal stores when
+     they otherwise wouldn't be used.  */
   if (non_temporal_threshold < minimum_non_temporal_threshold)
-    non_temporal_threshold = minimum_non_temporal_threshold;
+    non_temporal_threshold = 64 * 1024 * 1024;
   else if (non_temporal_threshold > maximum_non_temporal_threshold)
     non_temporal_threshold = maximum_non_temporal_threshold;