On Thu, Aug 31, 2023 at 6:57 AM Ken Matsui <kmat...@cs.washington.edu> wrote:
>
> On Tue, Aug 8, 2023 at 1:19 PM Jonathan Wakely <jwak...@redhat.com> wrote:
> >
> >
> >
> > On Tue, 18 Jul 2023 at 07:25, Ken Matsui via Libstdc++ 
> > <libstd...@gcc.gnu.org> wrote:
> >>
> >> Hi,
> >>
> >> I took a benchmark for this.
> >>
> >> https://github.com/ken-matsui/gcc-benches/blob/main/is_fundamental-disjunction.md#mon-jul-17-105937-pm-pdt-2023
> >>
> >> template<typename _Tp>
> >> struct is_fundamental
> >> : public std::bool_constant<__is_arithmetic(_Tp)
> >>                             || std::is_void<_Tp>::value
> >>                             || std::is_null_pointer<_Tp>::value>
> >> { };
> >>
> >> is faster than:
> >>
> >> template<typename _Tp>
> >> struct is_fundamental
> >> : public std::bool_constant<__is_arithmetic(_Tp)
> >>                             || std::disjunction<std::is_void<_Tp>,
> >>                                                 std::is_null_pointer<_Tp>
> >>                                                 >::value>
> >> { };
> >>
> >> Time: -32.2871%
> >> Peak Memory: -18.5071%
> >> Total Memory: -20.1991%
> >
> >
> > But what about the fallback implementation of is_fundamental where we don't 
> > have the __is_arithmetic built-in?
>
> That fallback implementation would be this:
> https://github.com/ken-matsui/gsoc23/blob/967e20770599f2a8925c9794669111faef11beb7/is_fundamental.cc#L11-L15.
>
> The is_fundamental-disjunction.cc benchmark used the USE_BUILTIN
> macro, but in this benchmark, I used it to just switch two different
> implementations that use the __is_arithmetic built-in.
>
> > -    : public __or_<is_arithmetic<_Tp>, is_void<_Tp>,
> > -                  is_null_pointer<_Tp>>::type
> > +    : public __bool_constant<is_arithmetic<_Tp>::value
> > +                             || is_void<_Tp>::value
> > +                             || is_null_pointer<_Tp>::value>
> >
> > Here the use of __or_ means that for is_fundamental<int> we don't 
> > instantiate is_void<int> and is_null_pointer<int>. Isn't that still 
> > worthwhile?
> >
> Let me take a benchmark with __or_ later! We may see a difference.
>
Here is the benchmark result with __or_:

https://github.com/ken-matsui/gsoc23/blob/main/is_fundamental-disjunction.md#thu-aug-31-075127-am-pdt-2023

Time: -23.3935%
Peak Memory: -10.2915%
Total Memory: -14.4165%

Considering the following was with disjunction, __or_ is faster than
disjunction, but still just || seems much faster.

Time: -32.2871%
Peak Memory: -18.5071%
Total Memory: -20.1991%

> >
> >
> >
> >>
> >>
> >> Sincerely,
> >> Ken Matsui
> >>
> >> On Sun, Jul 16, 2023 at 9:49 PM Ken Matsui <kmat...@cs.washington.edu> 
> >> wrote:
> >> >
> >> > On Sun, Jul 16, 2023 at 5:41 AM François Dumont <frs.dum...@gmail.com> 
> >> > wrote:
> >> > >
> >> > >
> >> > > On 15/07/2023 06:55, Ken Matsui via Libstdc++ wrote:
> >> > > > This patch optimizes the performance of the is_fundamental trait by
> >> > > > dispatching to the new __is_arithmetic built-in trait.
> >> > > >
> >> > > > libstdc++-v3/ChangeLog:
> >> > > >
> >> > > >       * include/std/type_traits (is_fundamental_v): Use 
> >> > > > __is_arithmetic
> >> > > >       built-in trait.
> >> > > >       (is_fundamental): Likewise. Optimize the original 
> >> > > > implementation.
> >> > > >
> >> > > > Signed-off-by: Ken Matsui <kmat...@gcc.gnu.org>
> >> > > > ---
> >> > > >   libstdc++-v3/include/std/type_traits | 21 +++++++++++++++++----
> >> > > >   1 file changed, 17 insertions(+), 4 deletions(-)
> >> > > >
> >> > > > diff --git a/libstdc++-v3/include/std/type_traits 
> >> > > > b/libstdc++-v3/include/std/type_traits
> >> > > > index 7ebbe04c77b..cf24de2fcac 100644
> >> > > > --- a/libstdc++-v3/include/std/type_traits
> >> > > > +++ b/libstdc++-v3/include/std/type_traits
> >> > > > @@ -668,11 +668,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >> > > >   #endif
> >> > > >
> >> > > >     /// is_fundamental
> >> > > > +#if __has_builtin(__is_arithmetic)
> >> > > > +  template<typename _Tp>
> >> > > > +    struct is_fundamental
> >> > > > +    : public __bool_constant<__is_arithmetic(_Tp)
> >> > > > +                             || is_void<_Tp>::value
> >> > > > +                             || is_null_pointer<_Tp>::value>
> >> > > > +    { };
> >> > >
> >> > > What about doing this ?
> >> > >
> >> > >    template<typename _Tp>
> >> > >      struct is_fundamental
> >> > >      : public __bool_constant<__is_arithmetic(_Tp)
> >> > >                               || __or_<is_void<_Tp>,
> >> > >                                       is_null_pointer<_Tp>>::value>
> >> > >      { };
> >> > >
> >> > > Based on your benches it seems that builtin __is_arithmetic is much 
> >> > > better that std::is_arithmetic. But __or_ could still avoid 
> >> > > instantiation of is_null_pointer.
> >> > >
> >> > Let me take a benchmark for this later.
> >>

Reply via email to