public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
* atomic<aligned_storage<16, 16>::type>.is_lock_free() on 3570K with -march=native
@ 2020-12-22  6:17 Jim Hill
  2020-12-22 11:50 ` Jonathan Wakely
  0 siblings, 1 reply; 4+ messages in thread
From: Jim Hill @ 2020-12-22  6:17 UTC (permalink / raw)
  To: libstdc++

`g++ -march=native` on my 3570k compiles the below code but fails to
link, showing

    atomic.cc:(.text.startup+0x24): undefined reference to
`__atomic_is_lock_free'

    #include <iostream>
    #include <atomic>
    int main(int c, char **v, char **e)
    {
      using namespace std;
      cout<<boolalpha<< atomic<aligned_storage<16,16>::type>().is_lock_free();
    }

where the code (and the program it's condensed from) work fine with `<8,8>`.

But the 3570K shows CMPXCHG16B support everywhere I can find.

Is this an oversight? A packaging/build error in my distro? I can work around
it for my current use, and if it's been missing this long I expect I'm in a
small handful of users who care at all, but if it's broken and fixable that'd
be great.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: atomic<aligned_storage<16, 16>::type>.is_lock_free() on 3570K with -march=native
  2020-12-22  6:17 atomic<aligned_storage<16, 16>::type>.is_lock_free() on 3570K with -march=native Jim Hill
@ 2020-12-22 11:50 ` Jonathan Wakely
  2020-12-22 19:30   ` Jim Hill
  2020-12-22 22:38   ` Jim Hill
  0 siblings, 2 replies; 4+ messages in thread
From: Jonathan Wakely @ 2020-12-22 11:50 UTC (permalink / raw)
  To: Jim Hill; +Cc: libstdc++

On Tue, 22 Dec 2020 at 06:18, Jim Hill via Libstdc++
<libstdc++@gcc.gnu.org> wrote:
>
> `g++ -march=native` on my 3570k compiles the below code but fails to
> link, showing
>
>     atomic.cc:(.text.startup+0x24): undefined reference to
> `__atomic_is_lock_free'
>
>     #include <iostream>
>     #include <atomic>
>     int main(int c, char **v, char **e)
>     {
>       using namespace std;
>       cout<<boolalpha<< atomic<aligned_storage<16,16>::type>().is_lock_free();
>     }
>
> where the code (and the program it's condensed from) work fine with `<8,8>`.
>
> But the 3570K shows CMPXCHG16B support everywhere I can find.
>
> Is this an oversight? A packaging/build error in my distro? I can work around
> it for my current use, and if it's been missing this long I expect I'm in a
> small handful of users who care at all, but if it's broken and fixable that'd
> be great.

This is not an oversight. Unless you compile with -mcx16 GCC will not
use the CMPXCHG16B instruction. That is to retain ABI compatibility
with code built with older versions of GCC and for older processors.
Because it doesn't use the instruction, it emits a call to an external
library function, so you need to link with -latomic (or provide your
own definitions of the required functions).

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: atomic<aligned_storage<16, 16>::type>.is_lock_free() on 3570K with -march=native
  2020-12-22 11:50 ` Jonathan Wakely
@ 2020-12-22 19:30   ` Jim Hill
  2020-12-22 22:38   ` Jim Hill
  1 sibling, 0 replies; 4+ messages in thread
From: Jim Hill @ 2020-12-22 19:30 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: libstdc++

On Tue, Dec 22, 2020 at 3:50 AM Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
> compile with -mcx16

And yet

    g++ -march=native -pipe -Os  -mcx16  -latomic atomic2.cc -o bin/atomic2

with this code

    #include <iostream>
    #include <atomic>
    int main(int c, char **v, char **e)
    {
            using namespace std;
            using a16 = aligned_storage<16,16>::type;
            using i16 = __int128 __attribute__((aligned(16)));
            struct asr;
            struct data {asr *a,*b;};
            union v16 { data v; a16 align; };

            cout<<boolalpha<< atomic<a16>().is_lock_free() <<'\n'
                           << atomic<v16>().is_lock_free() <<'\n'
                           << atomic<data>().is_lock_free() <<'\n'
                           << atomic<i16>().is_lock_free() <<'\n';
            atomic<a16> ta{}; a16 ta1{},ta2{};
            atomic<v16> tv{}; v16 tv1{},tv2{};
            atomic<i16> tu{}; i16 tu1{},tu2{};
            cout<<ta.compare_exchange_strong(ta1,ta2)<<'\n';
            cout<<tv.compare_exchange_strong(tv1,tv2)<<'\n';
            cout<<tu.compare_exchange_strong(tu1,tu2)<<'\n';
    }

produces four "false"s (followed by the three optimizer-discouragement
trues) and the
object code contains no cmpxchg16b's, just library calls.

I get the feeling I'm missing something obvious, but the `__int128`
result in particular
seems clearly wrong to me. Please forgive me if I'm blindspotting
here, a hint about
where I should look if that's the case would be most welcome.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: atomic<aligned_storage<16, 16>::type>.is_lock_free() on 3570K with -march=native
  2020-12-22 11:50 ` Jonathan Wakely
  2020-12-22 19:30   ` Jim Hill
@ 2020-12-22 22:38   ` Jim Hill
  1 sibling, 0 replies; 4+ messages in thread
From: Jim Hill @ 2020-12-22 22:38 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: libstdc++

.. . . ah. Okay. I've found the previous discussions on this issue,
for instance https://gcc.gnu.org/legacy-ml/gcc/2018-02/msg00224.html
and many more.

I gather std::atomic can't be implemented completely lock-free for
128-bit values on x86, because the only 16-byte atomics available
there are read-modify-writes like cmpxchg, which means the cpu can't
do such large loads from ROM atomically and `is_lock_free()` doesn't
have an "except from ROM" reply value. So I understand the raft of
`false` results for is_lock_free.

And since I'd have to put x86-specific tests in the code anyway to
deal with that grossness, if I ever really really have to have a
128-bit lock-free atomic a quick little glop of inline asm while I'm
there is a while-I'm-down-there-anyway thing,

It'd be nice if -mcx16 really did enable cmpxchg16b generation by
std::atomics, but even if it did that I'd have to put Big Fat Warnings
in my code about what is_lock_free's result really means, so the
choices are either everybody but libstdc++ has special-case code to
deal with it or everybody *and* llibstdc++ has special-case code to
deal with it. Color me grumpy, but, yeah, there's nothing more to be
done until some standardese way of expressing the x86's limitations
shows up.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-12-22 22:38 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-22  6:17 atomic<aligned_storage<16, 16>::type>.is_lock_free() on 3570K with -march=native Jim Hill
2020-12-22 11:50 ` Jonathan Wakely
2020-12-22 19:30   ` Jim Hill
2020-12-22 22:38   ` Jim Hill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).