From dd6afe349b7a4c2ab294c57b35fae2edddbb5925 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Tue, 15 Aug 2023 11:11:47 +0300 Subject: [PATCH 1/3] Avoid calling `size()` in valarray loops --- stl/inc/valarray | 80 +++++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/stl/inc/valarray b/stl/inc/valarray index cb360998f34..28dadf8a9c7 100644 --- a/stl/inc/valarray +++ b/stl/inc/valarray @@ -166,7 +166,7 @@ public: } valarray& operator=(const _Ty& _Val) { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Myptr[_Idx] = _Val; } @@ -192,7 +192,7 @@ public: valarray& operator=(const indirect_array<_Ty>& _Indarr); // defined below _NODISCARD valarray operator+() const { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization valarray<_Ty> _Ans(_Size); for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Ans[_Idx] = +_Myptr[_Idx]; @@ -201,7 +201,7 @@ public: } _NODISCARD valarray operator-() const { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization valarray<_Ty> _Ans(_Size); for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Ans[_Idx] = -_Myptr[_Idx]; @@ -210,7 +210,7 @@ public: } _NODISCARD valarray operator~() const { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization valarray<_Ty> _Ans(_Size); for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Ans[_Idx] = ~_Myptr[_Idx]; @@ -219,7 +219,7 @@ public: } _NODISCARD _Boolarray operator!() const { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization valarray _Ans(_Size); for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Ans[_Idx] = !_Myptr[_Idx]; @@ -228,7 +228,7 @@ public: } valarray& operator*=(const _Ty& _Right) { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Myptr[_Idx] *= _Right; } @@ -236,7 +236,7 @@ public: } valarray& operator/=(const _Ty& _Right) { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Myptr[_Idx] /= _Right; } @@ -244,7 +244,7 @@ public: } valarray& operator%=(const _Ty& _Right) { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Myptr[_Idx] %= _Right; } @@ -252,7 +252,7 @@ public: } valarray& operator+=(const _Ty& _Right) { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Myptr[_Idx] += _Right; } @@ -260,7 +260,7 @@ public: } valarray& operator-=(const _Ty& _Right) { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Myptr[_Idx] -= _Right; } @@ -268,7 +268,7 @@ public: } valarray& operator^=(const _Ty& _Right) { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Myptr[_Idx] ^= _Right; } @@ -276,7 +276,7 @@ public: } valarray& operator&=(const _Ty& _Right) { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Myptr[_Idx] &= _Right; } @@ -284,7 +284,7 @@ public: } valarray& operator|=(const _Ty& _Right) { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Myptr[_Idx] |= _Right; } @@ -292,7 +292,7 @@ public: } valarray& operator<<=(const _Ty& _Right) { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Myptr[_Idx] <<= _Right; } @@ -300,7 +300,7 @@ public: } valarray& operator>>=(const _Ty& _Right) { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Myptr[_Idx] >>= _Right; } @@ -308,7 +308,7 @@ public: } valarray& operator*=(const valarray& _Right) { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Myptr[_Idx] *= _Right[_Idx]; } @@ -316,7 +316,7 @@ public: } valarray& operator/=(const valarray& _Right) { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Myptr[_Idx] /= _Right[_Idx]; } @@ -324,7 +324,7 @@ public: } valarray& operator%=(const valarray& _Right) { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Myptr[_Idx] %= _Right[_Idx]; } @@ -332,7 +332,7 @@ public: } valarray& operator+=(const valarray& _Right) { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Myptr[_Idx] += _Right[_Idx]; } @@ -340,7 +340,7 @@ public: } valarray& operator-=(const valarray& _Right) { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Myptr[_Idx] -= _Right[_Idx]; } @@ -348,7 +348,7 @@ public: } valarray& operator^=(const valarray& _Right) { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Myptr[_Idx] ^= _Right[_Idx]; } @@ -356,7 +356,7 @@ public: } valarray& operator|=(const valarray& _Right) { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Myptr[_Idx] |= _Right[_Idx]; } @@ -364,7 +364,7 @@ public: } valarray& operator&=(const valarray& _Right) { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Myptr[_Idx] &= _Right[_Idx]; } @@ -372,7 +372,7 @@ public: } valarray& operator<<=(const valarray& _Right) { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Myptr[_Idx] <<= _Right[_Idx]; } @@ -380,7 +380,7 @@ public: } valarray& operator>>=(const valarray& _Right) { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Myptr[_Idx] >>= _Right[_Idx]; } @@ -424,7 +424,7 @@ public: _NODISCARD indirect_array<_Ty> operator[](const _Sizarray& _Indarr); // defined below _NODISCARD _Ty sum() const { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization _Ty _Sum = _Myptr[0]; for (size_t _Idx = 1; _Idx < _Size; ++_Idx) { _Sum += _Myptr[_Idx]; @@ -434,7 +434,7 @@ public: } _NODISCARD _Ty(min)() const { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization _Ty _Min = _Myptr[0]; for (size_t _Idx = 1; _Idx < _Size; ++_Idx) { if (_Myptr[_Idx] < _Min) { @@ -446,7 +446,7 @@ public: } _NODISCARD _Ty(max)() const { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization _Ty _Max = _Myptr[0]; for (size_t _Idx = 1; _Idx < _Size; ++_Idx) { if (_Max < _Myptr[_Idx]) { @@ -458,7 +458,7 @@ public: } _NODISCARD valarray shift(int _Count) const { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization valarray<_Ty> _Ans(_Size); size_t _Min = 0; size_t _Max = _Size; @@ -480,7 +480,7 @@ public: } _NODISCARD valarray cshift(int _Count) const { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization if (_Size != 0) { if (_Count < 0) { // right shift if (_Size < size_t{0} - _Count) { @@ -502,7 +502,7 @@ public: } _NODISCARD valarray apply(_Ty _Func(_Ty)) const { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization valarray<_Ty> _Ans(_Size); for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Ans[_Idx] = _Func(_Myptr[_Idx]); @@ -512,7 +512,7 @@ public: _NODISCARD valarray apply(_Ty _Func(const _Ty&)) const { // return valarray transformed by _Func, nonmutable argument - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization valarray<_Ty> _Ans(_Size); for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Ans[_Idx] = _Func(_Myptr[_Idx]); @@ -555,10 +555,12 @@ private: void _Tidy_deallocate() noexcept { if (_Myptr) { // destroy elements - for (size_t _Idx = 0; _Idx < _Mysize; ++_Idx) { - _Destroy_in_place(_Myptr[_Idx]); + if constexpr (!is_trivially_destructible<_Ty>::value) { + const size_t _Size = _Mysize; // eliminating indirection helps vectorization + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Destroy_in_place(_Myptr[_Idx]); + } } - #ifdef __cpp_aligned_new constexpr bool _Extended_alignment = alignof(_Ty) > __STDCPP_DEFAULT_NEW_ALIGNMENT__; if constexpr (_Extended_alignment) { @@ -574,7 +576,7 @@ private: } void _Assign(size_t _Newsize, const _Ty* _Ptr) { - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization if (_Size == _Newsize) { for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Myptr[_Idx] = _Ptr[_Idx]; @@ -1988,7 +1990,7 @@ valarray<_Ty>& valarray<_Ty>::operator=(const gslice_array<_Ty>& _Gslicearr) { _Tidy_deallocate(); _Grow(_Gslicearr._Totlen()); _Sizarray _Indexarray(size_t{0}, _Gslicearr._Nslice()); - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Myptr[_Idx] = _Gslicearr._Data(_Gslicearr._Off(_Indexarray)); } @@ -2011,7 +2013,7 @@ valarray<_Ty>& valarray<_Ty>::operator=(const mask_array<_Ty>& _Maskarr) { _Grow(_Maskarr._Totlen()); size_t _Count = 0; - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization for (size_t _Idx = 0; _Idx < _Size; ++_Count) { if (_Maskarr._Mask(_Count)) { _Myptr[_Idx++] = _Maskarr._Data(_Count); @@ -2035,7 +2037,7 @@ template valarray<_Ty>& valarray<_Ty>::operator=(const indirect_array<_Ty>& _Indarr) { _Tidy_deallocate(); _Grow(_Indarr._Totlen()); - const size_t _Size = size(); + const size_t _Size = _Mysize; // eliminating indirection helps vectorization for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Myptr[_Idx] = _Indarr._Data(_Indarr._Indir(_Idx)); } From b93df01130e6a9ff35523972e95c9768aa79ba5b Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 15 Aug 2023 17:34:05 -0700 Subject: [PATCH 2/3] Use variable templates for type traits. --- stl/inc/valarray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/valarray b/stl/inc/valarray index 28dadf8a9c7..f54618bb959 100644 --- a/stl/inc/valarray +++ b/stl/inc/valarray @@ -555,7 +555,7 @@ private: void _Tidy_deallocate() noexcept { if (_Myptr) { // destroy elements - if constexpr (!is_trivially_destructible<_Ty>::value) { + if constexpr (!is_trivially_destructible_v<_Ty>) { const size_t _Size = _Mysize; // eliminating indirection helps vectorization for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Destroy_in_place(_Myptr[_Idx]); From f0e739be66d21e88094523e954c367b75e8caad7 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Tue, 29 Aug 2023 13:57:35 -0700 Subject: [PATCH 3/3] Casey's review comment --- stl/inc/valarray | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/stl/inc/valarray b/stl/inc/valarray index f54618bb959..e62943f2fe0 100644 --- a/stl/inc/valarray +++ b/stl/inc/valarray @@ -555,12 +555,7 @@ private: void _Tidy_deallocate() noexcept { if (_Myptr) { // destroy elements - if constexpr (!is_trivially_destructible_v<_Ty>) { - const size_t _Size = _Mysize; // eliminating indirection helps vectorization - for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { - _Destroy_in_place(_Myptr[_Idx]); - } - } + _Destroy_range(_Myptr, _Myptr + _Mysize); #ifdef __cpp_aligned_new constexpr bool _Extended_alignment = alignof(_Ty) > __STDCPP_DEFAULT_NEW_ALIGNMENT__; if constexpr (_Extended_alignment) {