Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement vectorized min_ / max_element for ints #2447

Merged
merged 66 commits into from
Jun 19, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
2951f9e
Implement vectorized min_ / max_element for ints
AlexGuteniev Dec 26, 2021
19ba1d0
fix copypasta
AlexGuteniev Dec 26, 2021
44b19c9
Guard C++ features
AlexGuteniev Dec 26, 2021
7c233f4
typo
AlexGuteniev Dec 26, 2021
e245018
@miscco review
AlexGuteniev Dec 26, 2021
3bf81a7
contexpr in C++14 / C++17 :-(
AlexGuteniev Dec 26, 2021
f781a70
Fix algorithm
AlexGuteniev Dec 26, 2021
34b935d
x86 build
AlexGuteniev Dec 26, 2021
de0397a
minmax_element
AlexGuteniev Dec 26, 2021
f118d4c
fix corner case; +comments
AlexGuteniev Dec 26, 2021
bc6a055
misleading comments
AlexGuteniev Dec 26, 2021
6a7708e
enable x86 function fusion optimziation
AlexGuteniev Dec 26, 2021
64b9e80
Comment on __stdcall
AlexGuteniev Dec 26, 2021
8e2bf94
-stray def param
AlexGuteniev Dec 26, 2021
300b3b4
literate
AlexGuteniev Dec 26, 2021
7597d6f
Simplify _Base
AlexGuteniev Dec 26, 2021
0519a3e
strange, tests locally pass for me
AlexGuteniev Dec 26, 2021
4246874
try to undo __std_minmax_element
AlexGuteniev Dec 26, 2021
121ea2a
ptrptr
AlexGuteniev Dec 26, 2021
2a7b50b
minmax element wrapper
AlexGuteniev Dec 27, 2021
6664519
minmax
AlexGuteniev Dec 27, 2021
d0ccf20
fix minmax_element for larger value type
AlexGuteniev Dec 27, 2021
24dbd57
some test coverage
AlexGuteniev Dec 27, 2021
3ed6d99
Fix x86 64-bit handling
AlexGuteniev Dec 27, 2021
2b43c89
minor cleanup
AlexGuteniev Dec 27, 2021
137f413
more text cleanup
AlexGuteniev Dec 27, 2021
f01c3c6
-stdlib dependency
AlexGuteniev Dec 27, 2021
d5ab6ac
superfluous
AlexGuteniev Dec 28, 2021
7564248
LT is superfluous
AlexGuteniev Dec 28, 2021
04b72fa
optimize 16-bit case
AlexGuteniev Dec 29, 2021
f4220f3
Fix for optimization of 16-bit
AlexGuteniev Dec 29, 2021
28389bb
enable for any standard mode
AlexGuteniev Jan 2, 2022
92fbbda
guard __CUDACC__
AlexGuteniev Jan 2, 2022
53c6796
reduce repeated code
AlexGuteniev Jan 2, 2022
fb7679d
Element in name
AlexGuteniev Jan 3, 2022
8f91c0d
optimization tuning for release only
AlexGuteniev Jan 3, 2022
4f289c0
Merge remote-tracking branch 'upstream/main' into vector_max
AlexGuteniev Jan 20, 2022
fe29701
Merge remote-tracking branch 'upstream/main' into vector_max
AlexGuteniev Apr 2, 2022
661fd86
Missing typename
AlexGuteniev Apr 2, 2022
c451f69
pointer cast properly
AlexGuteniev Apr 2, 2022
87992c1
narrative
AlexGuteniev Apr 2, 2022
66943a8
unnamed namespace
AlexGuteniev Apr 5, 2022
962b91d
Merge remote-tracking branch 'upstream/main' into vector_max
AlexGuteniev Apr 5, 2022
d077514
extern C
AlexGuteniev Apr 5, 2022
5913478
Merge remote-tracking branch 'upstream/main' into vector_max
AlexGuteniev Apr 23, 2022
d5953f5
more obvious all FFs
AlexGuteniev May 5, 2022
881f1e2
bitwise flags, aligned loads
AlexGuteniev May 10, 2022
8912c70
format
AlexGuteniev May 10, 2022
c02cb63
brace
AlexGuteniev May 10, 2022
ef213be
unternary
AlexGuteniev May 12, 2022
40c323f
Update vector_algorithms.cpp
AlexGuteniev May 12, 2022
856da66
_Ugly
AlexGuteniev May 12, 2022
7e7683f
review comments
AlexGuteniev May 13, 2022
4f332e3
+coverage
AlexGuteniev May 14, 2022
bdf7d82
+coverage
AlexGuteniev May 14, 2022
b79b194
format
AlexGuteniev May 14, 2022
a6ffe63
enhance special cases
AlexGuteniev May 28, 2022
9c6ba04
format
AlexGuteniev May 28, 2022
17e3b25
bring back a needed include
AlexGuteniev May 28, 2022
679e65d
Merge remote-tracking branch 'upstream/main' into vector_max
AlexGuteniev Jun 11, 2022
5c42c76
Merge branch 'main' into vector_max
StephanTLavavej Jun 18, 2022
56799e8
Code review feedback.
StephanTLavavej Jun 18, 2022
f538bbc
Remove workarounds now that we have 17.3 Preview 2.
StephanTLavavej Jun 18, 2022
1172483
Rename "cor" to "correction".
StephanTLavavej Jun 18, 2022
f566426
Remove CUDA guards.
StephanTLavavej Jun 18, 2022
d178303
Restore perma-workarounds.
StephanTLavavej Jun 19, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions stl/inc/algorithm
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,68 @@ __declspec(noalias) void __cdecl __std_reverse_copy_trivially_copyable_4(
const void* _First, const void* _Last, void* _Dest) noexcept;
__declspec(noalias) void __cdecl __std_reverse_copy_trivially_copyable_8(
const void* _First, const void* _Last, void* _Dest) noexcept;

struct _Min_max_t {
const void* _Min;
const void* _Max;
};

const void* __stdcall __std_min_element_1(const void* _First, const void* _Last, bool _Signed) noexcept;
const void* __stdcall __std_min_element_2(const void* _First, const void* _Last, bool _Signed) noexcept;
const void* __stdcall __std_min_element_4(const void* _First, const void* _Last, bool _Signed) noexcept;
const void* __stdcall __std_min_element_8(const void* _First, const void* _Last, bool _Signed) noexcept;

const void* __stdcall __std_max_element_1(const void* _First, const void* _Last, bool _Signed) noexcept;
const void* __stdcall __std_max_element_2(const void* _First, const void* _Last, bool _Signed) noexcept;
const void* __stdcall __std_max_element_4(const void* _First, const void* _Last, bool _Signed) noexcept;
const void* __stdcall __std_max_element_8(const void* _First, const void* _Last, bool _Signed) noexcept;

_Min_max_t __stdcall __std_minmax_element_1(const void* _First, const void* _Last, bool _Signed) noexcept;
_Min_max_t __stdcall __std_minmax_element_2(const void* _First, const void* _Last, bool _Signed) noexcept;
_Min_max_t __stdcall __std_minmax_element_4(const void* _First, const void* _Last, bool _Signed) noexcept;
_Min_max_t __stdcall __std_minmax_element_8(const void* _First, const void* _Last, bool _Signed) noexcept;

_END_EXTERN_C

template <class _Ty>
_Ty* __std_min_element(_Ty* _First, _Ty* _Last) noexcept {
using cv_pv = _STD conditional_t<_STD is_const_v<_Ty>, const void*, void*>;
constexpr bool _Signed = _STD is_signed_v<_Ty>;

if constexpr (_STD is_pointer_v<_Ty> || _STD is_null_pointer_v<_Ty>) {
return __std_min_element(_First, _Last);
} else if constexpr (sizeof(_Ty) == 1) {
return static_cast<_Ty*>(const_cast<cv_pv>(__std_min_element_1(_First, _Last, _Signed)));
} else if constexpr (sizeof(_Ty) == 2) {
return static_cast<_Ty*>(const_cast<cv_pv>(__std_min_element_2(_First, _Last, _Signed)));
} else if constexpr (sizeof(_Ty) == 4) {
return static_cast<_Ty*>(const_cast<cv_pv>(__std_min_element_4(_First, _Last, _Signed)));
} else if constexpr (sizeof(_Ty) == 8) {
return static_cast<_Ty*>(const_cast<cv_pv>(__std_min_element_8(_First, _Last, _Signed)));
} else {
static_assert(_STD _Always_false<_Ty>, "Unexpected size");
}
}

template <class _Ty>
_Ty* __std_max_element(_Ty* _First, _Ty* _Last) noexcept {
using cv_pv = _STD conditional_t<_STD is_const_v<_Ty>, const void*, void*>;
constexpr bool _Signed = _STD is_signed_v<_Ty>;

if constexpr (_STD is_pointer_v<_Ty> || _STD is_null_pointer_v<_Ty>) {
return __std_max_element(_First, _Last);
} else if constexpr (sizeof(_Ty) == 1) {
return static_cast<_Ty*>(const_cast<cv_pv>(__std_max_element_1(_First, _Last, _Signed)));
} else if constexpr (sizeof(_Ty) == 2) {
return static_cast<_Ty*>(const_cast<cv_pv>(__std_max_element_2(_First, _Last, _Signed)));
} else if constexpr (sizeof(_Ty) == 4) {
return static_cast<_Ty*>(const_cast<cv_pv>(__std_max_element_4(_First, _Last, _Signed)));
} else if constexpr (sizeof(_Ty) == 8) {
return static_cast<_Ty*>(const_cast<cv_pv>(__std_max_element_8(_First, _Last, _Signed)));
} else {
static_assert(_STD _Always_false<_Ty>, "Unexpected size");
}
}
#endif // _USE_STD_VECTOR_ALGORITHMS

_STD_BEGIN
Expand Down Expand Up @@ -9228,8 +9289,29 @@ namespace ranges {
#endif // __cpp_lib_concepts
#endif // _HAS_CXX17

template <class _FwdIt, class _Pr>
_INLINE_VAR constexpr bool _Is_min_max_optimization_safe =
AlexGuteniev marked this conversation as resolved.
Show resolved Hide resolved
_Iterator_is_contiguous<_FwdIt>&&
conjunction_v<disjunction<is_integral<_Iter_value_t<_FwdIt>>, is_pointer<_Iter_value_t<_FwdIt>>>,
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
disjunction<is_same<_Pr, less<>>, is_same<_Pr, _RANGES less>,
is_same<_Pr, less<_Iter_value_t<_FwdIt>>>>> && !is_volatile_v<remove_reference_t<_Iter_ref_t<_FwdIt>>>;

template <class _FwdIt, class _Pr>
constexpr _FwdIt _Max_element_unchecked(_FwdIt _First, _FwdIt _Last, _Pr _Pred) { // find largest element
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
#if _USE_STD_VECTOR_ALGORITHMS
if (!is_constant_evaluated()) {
AlexGuteniev marked this conversation as resolved.
Show resolved Hide resolved
if constexpr (_Is_min_max_optimization_safe<_FwdIt, _Pr>) {
AlexGuteniev marked this conversation as resolved.
Show resolved Hide resolved
const auto _First_ptr = _To_address(_First);
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
auto _Result = __std_max_element(_First_ptr, _To_address(_Last));
AlexGuteniev marked this conversation as resolved.
Show resolved Hide resolved
if constexpr (is_pointer_v<_FwdIt>) {
return _Result;
} else {
return _First + (_Result - _First_ptr);
}
AlexGuteniev marked this conversation as resolved.
Show resolved Hide resolved
}
}
#endif // _USE_STD_VECTOR_ALGORITHMS

_FwdIt _Found = _First;
if (_First != _Last) {
while (++_First != _Last) {
Expand Down Expand Up @@ -9321,6 +9403,20 @@ namespace ranges {

template <class _FwdIt, class _Pr>
constexpr _FwdIt _Min_element_unchecked(_FwdIt _First, _FwdIt _Last, _Pr _Pred) { // find smallest element
#if _USE_STD_VECTOR_ALGORITHMS
if (!is_constant_evaluated()) {
if constexpr (_Is_min_max_optimization_safe<_FwdIt, _Pr>) {
const auto _First_ptr = _To_address(_First);
auto _Result = __std_min_element(_First_ptr, _To_address(_Last));
if constexpr (is_pointer_v<_FwdIt>) {
return _Result;
} else {
return _First + (_Result - _First_ptr);
}
}
}
#endif // _USE_STD_VECTOR_ALGORITHMS

_FwdIt _Found = _First;
if (_First != _Last) {
while (++_First != _Last) {
Expand Down
Loading