microsoft / microsoft/snmalloc
16 byte cmpxchg
Open
Nobody has claimed this yet.
enhancement
- Dominant language
- C++
- Stars
- 2k
- Forks
- 138
- Avg merge
- 11h 19m
- Merged PRs (30d)
- 5
Description
I think there are two points to improve in current cmpxchg support for 16 byte data structures:
- consider arm lse
- consider using
__sync_bool_compare_and_swapto force gcc emit inlined instructions.
#include <atomic>
#if defined(__aarch64__) && defined(__clang__)
# pragma clang attribute push(__attribute__((target("lse"))),apply_to=function)
# define PLATFORM_SPECIFIC_OPTIONS_ENDING _Pragma("clang attribute pop")
#elif defined(__aarch64__) && defined(__GNUC__)
# pragma GCC push_options
# pragma GCC target("arch=armv8-a+lse")
# define PLATFORM_SPECIFIC_OPTIONS_ENDING _Pragma("GCC pop_options")
#elif defined(__x86_64__) && defined(__clang__)
# pragma clang attribute push(__attribute__((target("cx16"))),apply_to=function)
# define PLATFORM_SPECIFIC_OPTIONS_ENDING _Pragma("clang attribute pop")
#elif defined(__x86_64__) && defined(__GNUC__)
# pragma GCC push_options
# pragma GCC target("cx16")
# define PLATFORM_SPECIFIC_OPTIONS_ENDING _Pragma("GCC pop_options")
#else
# define PLATFORM_SPECIFIC_OPTIONS_ENDING
#endif
template<class T>
__attribute__((always_inline)) inline bool cas(std::atomic<T> &src,
T const& __restrict cmp,
T const& __restrict with)
{
auto inline_copy = [](__int128 * dst, const void * __restrict src) {
#if __has_builtin(__builtin_inline_memcpy)
__builtin_inline_memcpy(dst, src, sizeof(__int128));
#elif __has_builtin(__builtin_memcpy)
__builtin_memcpy(dst, src, sizeof(__int128));
#else
::memcpy(dst, src, sizeof(__int128));
#endif
};
__int128 cmp_value;
__int128 with_value;
inline_copy(&cmp_value, &cmp);
inline_copy(&with_value, &with);
return __sync_bool_compare_and_swap(reinterpret_cast<__int128 *>(&src), cmp_value, with_value);
}
struct A {
int64_t a, b;
};
bool cas_test(std::atomic<__int128> &src,
__int128 const& cmp,
__int128 const& with)
{
return cas(src, cmp, with);
}
bool cas_test(std::atomic<A> &src,
A const& cmp,
A const& with)
{
return cas(src, cmp, with);
}
PLATFORM_SPECIFIC_OPTIONS_ENDING
bool cas_test2(std::atomic<__int128> &src,
__int128 & cmp,
__int128 & with)
{
return src.compare_exchange_weak(cmp, with);
}
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the C++ reproduction in the issue, focusing on the cas and cas_test entry points and the compiler-specific target pragmas. Compare the current 16-byte cmpxchg behavior with ARM LSE and GCC's __sync_bool_compare_and_swap output; done means reaching an agreed implementation and validating the generated instructions across the named compiler and architecture combinations.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- performance
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100