On Donnerstag, 12. November 2020 00:43:31 CET Jonathan Wakely wrote:
> On 08/05/20 21:03 +0200, Matthias Kretz wrote:
> >Here's my last update to the std::experimental::simd patch. It's currently
> >based on the gcc-10 branch.
> >
> >
> >+
> >+// __next_power_of_2{{{
> >+/**
> >+ * \internal
> 
> We use @foo for Doxygen commens rather than \foo

Done.

> >+ * Returns the next power of 2 larger than or equal to \p __x.
> >+ */
> >+constexpr std::size_t
> >+__next_power_of_2(std::size_t __x)
> >+{
> >+  return (__x & (__x - 1)) == 0 ? __x
> >+                            : __next_power_of_2((__x | (__x >> 1)) + 1);
> >+}
> 
> Can this be replaced with std::__bit_ceil ?
> 
> std::bit_ceil is C++20, but we provide __private versions of
> everything in <bit> for C++14 and up.

Ah good. I'll delete some code.

> >+// vvv ---- type traits ---- vvv
> >+// integer type aliases{{{
> >+using _UChar = unsigned char;
> >+using _SChar = signed char;
> >+using _UShort = unsigned short;
> >+using _UInt = unsigned int;
> >+using _ULong = unsigned long;
> >+using _ULLong = unsigned long long;
> >+using _LLong = long long;
> 
> I have a suspicion some of these might clash with libc macros on some
> OS somewhere, but we can cross that bridge when we come to it.

I need those to help cutting down the code for 80 cols. ;-)

> >+// __make_dependent_t {{{
> >+template <typename, typename _Up> struct __make_dependent
> >+{
> >+  using type = _Up;
> >+};
> >+template <typename _Tp, typename _Up>
> >+using __make_dependent_t = typename __make_dependent<_Tp, _Up>::type;
> 
> Do you need a distinct class template for this, or can
> __make_dependent_t be an alias to __type_identity<T>::type or
> something else that already exists?

With GCC it would suffice to use __type_identity<T>::type here. But Clang 
rejects it. Clang sees that the first template argument is not used in the 
definition of the alias and thus doesn't make _Up a dependent type.

> >+// __call_with_n_evaluations{{{
> >+template <size_t... _I, typename _F0, typename _FArgs>
> >+_GLIBCXX_SIMD_INTRINSIC constexpr auto
> >+__call_with_n_evaluations(std::index_sequence<_I...>, _F0&& __f0,
> >+                      _FArgs&& __fargs)
> 
> I'm not sure if it matters here, but old versions of G++ passed empty
> types (like index_sequence) using the wrong ABI. Passing them as the
> last argument makes it a non-issue. If they're not the last argument,
> you get incompatible code when compiling with -fabi-version=7 or
> lower.

These are all [[gnu::always_inline]]. So it shouldn't matter.

> >+// __is_narrowing_conversion<_From, _To>{{{
> >+template <typename _From, typename _To, bool =
> >std::is_arithmetic<_From>::value, +    bool =
> >std::is_arithmetic<_To>::value>
> 
> These could use is_arithmetic_v.

Right. That was me trying to work around a clang-format bug. Will fix. I'm in 
the process of ditching clang-format anyway.

> >+{
> >+};
> >+
> >+template <typename _Tp>
> >+struct __is_narrowing_conversion<bool, _Tp, true, true> : public true_type
> 
> This looks odd, bool to arithmetic type T is narrowing?
> I assume there's a reason for it, so maybe a comment explaining it
> would help.

Odd indeed. Either I wanted to take a shortcut to implement: "From is a 
vectorizable type and every possibly value of From can be represented with 
type value_type, or [...]". Or I wanted to swap bool and _Tp here and say that 
anything other than bool converting to bool is narrowing.

I should clean this up.

> 
> >+// _BitOps {{{
> >+struct _BitOps
> > [...]
> std::__popcount in <bit>
> > [...]
> std::__countl_zero in <bit>

Yes. I'll clean up all of _BitOps.

> >+template <typename _V>
> 
> We generally avoid single letter names, although _V isn't in the list
> of BADNAMES in the manual, so maybe this one's OK.
> 
> >+template <typename _Tp, typename _TVT = _VectorTraits<_Tp>,
> >+      typename _R
> 
> Same for _R, it's not listed as a BADNAME.

I believe I checked the list. ;-)

> >+
> >+template <typename _Tp, typename = decltype(_Tp() & _Tp())>
> >+_GLIBCXX_SIMD_INTRINSIC constexpr _Tp
> >+__and(_Tp __a, _Tp __b) noexcept
> 
> Calls to __and are done unqualified. Are they only with types that
> won't cause ADL to look outside namespace std?
> 
> Even though __and is a reserved name, avoidign ADL has other benefits.

Called either with integers, [[gnu::vector_size(N)]] types, or 
std::experimental::parallelism_v2::_SimdWrapper. I request a column limit 
relaxation to at least 100 cols if I should qualify all of them with 
std::experimental:: ;-)

> That's all for now ... not very far through the huge patch though.
> Generally this looks very good. The things mentioned above are
> stylistic or just remove some redundancy, they're not critical.

Thanks. I'll post a new patch ASAP. My tests are running.

-Matthias

-- 
──────────────────────────────────────────────────────────────────────────
 Dr. Matthias Kretz                           https://mattkretz.github.io
 GSI Helmholtz Centre for Heavy Ion Research               https://gsi.de
 std::experimental::simd              https://github.com/VcDevel/std-simd
──────────────────────────────────────────────────────────────────────────



Reply via email to