| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
|
Couldn't get this to build on OSX 10.8 and Clang 3.2 (commit cc11a96) c++ '-D_DARWIN_USE_64_BIT_INODE=1' '-DNODE_ARCH="x64"' '-DNODE_WANT_INTERNALS=1' '-DV8_DEPRECATION_WARNINGS=1' '-DNODE_USE_V8_PLATFORM=1' '-DNODE_HAVE_I18N_SUPPORT=1' '-DNODE_HAVE_SMALL_ICU=1' '-DHAVE_INSPECTOR=1' '-DV8_INSPECTOR_USE_STL=1' '-DHAVE_OPENSSL=1' '-DHAVE_DTRACE=1' '-D__POSIX__' '-DNODE_PLATFORM="darwin"' '-DUCONFIG_NO_TRANSLITERATION=1' '-DUCONFIG_NO_SERVICE=1' '-DUCONFIG_NO_REGULAR_EXPRESSIONS=1' '-DU_ENABLE_DYLOAD=0' '-DU_STATIC_IMPLEMENTATION=1' '-DU_HAVE_STD_STRING=0' '-DUCONFIG_NO_BREAK_ITERATION=0' '-DUCONFIG_NO_LEGACY_CONVERSION=1' '-DUCONFIG_NO_CONVERSION=1' '-DHTTP_PARSER_STRICT=0' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' -I../src -I../tools/msvs/genfiles -I../deps/uv/src/ares -I/home/gib/node/out/Release/obj/gen -I../deps/v8_inspector -I../deps/v8_inspector/deps/wtf -I/home/gib/node/out/Release/obj/gen/blink -I../deps/v8/include -I../deps/icu-small/source/i18n -I../deps/icu-small/source/common -I../deps/openssl/openssl/include -I../deps/zlib -I../deps/http_parser -I../deps/cares/include -I../deps/uv/include -Os -gdwarf-2 -mmacosx-version-min=10.7 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -std=gnu++0x -fno-rtti -fno-exceptions -fno-threadsafe-statics -fno-strict-aliasing -MMD -MF /home/gib/node/out/Release/.deps//home/gib/node/out/Release/obj.target/node/src/async-wrap.o.d.raw -c -o /home/gib/node/out/Release/obj.target/node/src/async-wrap.o ../src/async-wrap.cc
/include -I../deps/uv/include -Os -gdwarf-2 -mmacosx-version-min=10.7 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -std=gnu++0x -fno-rtti -fno-exceptions -fno-threadsafe-statics -fno-strict-aliasing -MMD -MF /home/gib/node/out/Release/.deps//home/gib/node/out/Release/obj.target/node/src/handle_wrap.o.d.raw -c -o /home/gib/node/out/Release/obj.target/node/src/handle_wrap.o ../src/handle_wrap.cc
In file included from ../test/cctest/util.cc:2:
../src/util-inl.h:250:19: error: use of undeclared identifier '__builtin_bswap16'
data16[i] = BSWAP_INTRINSIC_2(data16[i]);
^
../src/util-inl.h:15:30: note: expanded from macro 'BSWAP_INTRINSIC_2'
#define BSWAP_INTRINSIC_2(x) __builtin_bswap16(x)
^
In file included from ../src/inspector_socket.cc:3:
../src/util-inl.h:250:19: error: use of undeclared identifier '__builtin_bswap16'
data16[i] = BSWAP_INTRINSIC_2(data16[i]);
^
../src/util-inl.h:15:30: note: expanded from macro 'BSWAP_INTRINSIC_2'
#define BSWAP_INTRINSIC_2(x) __builtin_bswap16(x)
^
In file included from ../src/env.cc:1:
In file included from ../src/env.h:7:
In file included from ../src/debug-agent.h:29:
../src/util-inl.h:250:19: error: use of undeclared identifier '__builtin_bswap16'
data16[i] = BSWAP_INTRINSIC_2(data16[i]);
^
../src/util-inl.h:15:30: note: expanded from macro 'BSWAP_INTRINSIC_2'
#define BSWAP_INTRINSIC_2(x) __builtin_bswap16(x)
^
In file included from ../src/cares_wrap.cc:4:
In file included from ../src/async-wrap-inl.h:8:
In file included from ../src/base-object-inl.h:7:
In file included from ../src/env.h:7:
In file included from ../src/debug-agent.h:29:
../src/util-inl.h:250:19: error: use of undeclared identifier '__builtin_bswap16'
data16[i] = BSWAP_INTRINSIC_2(data16[i]);
^
../src/util-inl.h:15:30: note: expanded from macro 'BSWAP_INTRINSIC_2'
#define BSWAP_INTRINSIC_2(x) __builtin_bswap16(x)
^
In file included from ../src/debug-agent.cc:22:
In file included from ../src/debug-agent.h:29:
../src/util-inl.h:250:19: error: use of undeclared identifier '__builtin_bswap16'
data16[i] = BSWAP_INTRINSIC_2(data16[i]);
^
../src/util-inl.h:15:30: note: expanded from macro 'BSWAP_INTRINSIC_2'
#define BSWAP_INTRINSIC_2(x) __builtin_bswap16(x)
^
In file included from ../src/fs_event_wrap.cc:2:
In file included from ../src/async-wrap-inl.h:8:
In file included from ../src/base-object-inl.h:7:
In file included from ../src/env.h:7:
In file included from ../src/debug-agent.h:29:
../src/util-inl.h:250:19: error: use of undeclared identifier '__builtin_bswap16'
data16[i] = BSWAP_INTRINSIC_2(data16[i]);
^
../src/util-inl.h:15:30: note: expanded from macro 'BSWAP_INTRINSIC_2'
#define BSWAP_INTRINSIC_2(x) __builtin_bswap16(x)
^
In file included from ../src/async-wrap.cc:2:
In file included from ../src/async-wrap-inl.h:8:
In file included from ../src/base-object-inl.h:7:
In file included from ../src/env.h:7:
In file included from ../src/debug-agent.h:29:
../src/util-inl.h:250:19: error: use of undeclared identifier '__builtin_bswap16'
data16[i] = BSWAP_INTRINSIC_2(data16[i]);
^
../src/util-inl.h:15:30: note: expanded from macro 'BSWAP_INTRINSIC_2'
#define BSWAP_INTRINSIC_2(x) __builtin_bswap16(x)
^
In file included from ../src/handle_wrap.cc:3:
In file included from ../src/async-wrap-inl.h:8:
In file included from ../src/base-object-inl.h:7:
In file included from ../src/env.h:7:
In file included from ../src/debug-agent.h:29:
../src/util-inl.h:250:19: error: use of undeclared identifier '__builtin_bswap16'
data16[i] = BSWAP_INTRINSIC_2(data16[i]);
^
../src/util-inl.h:15:30: note: expanded from macro 'BSWAP_INTRINSIC_2'
#define BSWAP_INTRINSIC_2(x) __builtin_bswap16(x)
^
EDIT: I ran make clean && ./configure && make -j8 CXX.host=c++. I'm happy to help with debugging @zbjornson (assuming I didn't somehow configure the build wrong). The same process worked with #7644 FWIW. |
Sorry, something went wrong.
There was a problem hiding this comment.
In-place modification of a const buffer is definitely not allowed.
Sorry, something went wrong.
There was a problem hiding this comment.
@bnoordhuis Does that mean this isn't possible?
Sorry, something went wrong.
There was a problem hiding this comment.
No, I just botched and misread the pointer reassignment in the original code. Will fix. Thanks for catching @bnoordhuis.
Sorry, something went wrong.
|
Sorry, turns out clang also defines __GNUC__ -- fixed. Also fixed the const buffer problem. Can you try again please? Thanks for your help @gibfahn. |
Sorry, something went wrong.
|
@zbjornson First off, thanks for taking the time to work on this. I don't think this PR is the way to go but that doesn't mean I don't appreciate you working on it. Knowing what I know of clang and gcc (and some quick tests confirm that), I don't think it's the use of intrinsics/builtins that is responsible for the performance improvement, it's that the compiler can:
If I rewrite #7644 to hint the same conditions to the compiler, I get comparable numbers on benchmark/buffers/buffer-swap.js in the aligned case. The compiler even emits the same machine code as when using the builtins. (I still need to look into the unaligned case. Perhaps there is something we can tweak there as well.) |
Sorry, something went wrong.
|
Interesting, okay. Keen to try out your reworked version. When I played with similar code, the compilers would only emit PSHUFB and similar with -O3, whereas the intrinsics always mapped correctly. |
Sorry, something went wrong.
I’d expect that to noticeably outperform the __bswap* intrinsics, but that instruction wouldn’t be available on all x64 CPUs, so at least the Linux binaries wouldn’t be able to leverage support for it. |
Sorry, something went wrong.
|
@addaleax err, I meant to say that this type of thing: char a = data[0];
data[0] = data[1];
data[1] = a;mapped to PSHUFB only with -O3, whereas the builtins reliably mapped to PSHUFB without -O3 (and afaik node is compiled with -Os and /Od). |
Sorry, something went wrong.
|
@zbjornson Ah – Either way, be aware that, without CPU detection or extra compiler flags, pshufb is something that won’t end up in Linux release builds, so I’d be careful with performance measurements on Mac (I’m assuming from the above that you are using a Mac).
Pretty sure it’s -O3 by default: Line 103 in fcae5e2 |
Sorry, something went wrong.
|
@addaleax ahh I'd been trying to find that info about whether or not AVX/SSE extensions will be used in release for quite some time, thanks! If that's the case, then it makes sense to use the smaller code from #7644. (I'd been benchmarking on Windows.) You're right on -O3. (The first line in #7645 (comment) has -Os for some reason, but a normal release build shows -O3.) |
Sorry, something went wrong.
|
@zbjornson This PR is now building cleanly on my 10.8 machine (d6147aef8e2e9511149cba5809e330fd318e6e38) |
Sorry, something went wrong.
|
@addaleax ... any further thoughts on this one? |
Sorry, something went wrong.
|
Note that I want to replace the std::swap calls with the char a = data[0]; data[0] = data[1]; data[1] = a; dance because it's faster. I delayed making that change because I wasn't sure if this would get merged. I think that because this is substantially faster on at least Windows, and potentially on custom builds on other platforms (to be tested), is a good reason to pursue this PR. I don't see any downsides at least. I can make the above change and do more benchmarking this week. |
Sorry, something went wrong.
|
@bnoordhuis So does this updated PR seem better to you? ref: #7618 (comment) |
Sorry, something went wrong.
There was a problem hiding this comment.
Nit: no space before (.
Sorry, something went wrong.
There was a problem hiding this comment.
Consider writing it as sizeof(dst[0]).
Sorry, something went wrong.
There was a problem hiding this comment.
Is this actually faster than std::swap or an inline function?
Sorry, something went wrong.
There was a problem hiding this comment.
This is a strict-aliasing violation, strictly speaking. My PR operates on just char for that reason.
Sorry, something went wrong.
|
Thanks for your review @bnoordhuis and again sorry that this small thing has dragged on. Revisions submitted. As far as the strict aliasing violation you pointed out: I admit that this confused me. When I've asked about reading from char buffers in particular, I get answers along the lines of "it's not UB or a SA violation," "it looks like one but it isn't because you assume that the original pointer is a uint16_t" or "it is but everyone does it" (which seems to be the most correct of the three) (see ref1, ref2 (and later replies)). Note that the violation already existed in string_bytes.cc and this PR just relocates it: As far as avoiding the violation:
Thus, in the latest revision, I use reinterpret_cast on Windows and eliminated for the rest. What do you think about that? That yields these benchmarks, which are about as good as they get (with node's default build config) aside from aligned 16 on linux (per above): |
Sorry, something went wrong.
It is and that is why node.js is currently built with -fno-strict-aliasing. Still, I'd prefer to avoid aliasing if reasonably possible.
That is not what the spec says and not how gcc and clang operate when -fstrict-aliasing is in effect. The rule is unambiguous: no pointer can alias another pointer unless the alias is of type char*. Think of it like this: when strict aliasing is in effect, and when there are no char* pointers in scope, the compiler can assume that values it is trying to read or write through a pointer will not change underneath it. With -fno-strict-aliasing, gcc and clang conservatively assume that every pointer is being aliased somewhere unless it is trivial to prove otherwise; it's infeasible to track aliasing program-wide. (Incidentally, that is why the return values of malloc, calloc and operator new are marked as noalias. They logically can't alias other pointers but if the compiler didn't know that, it would have to assume the worst and emit significantly worse code around dynamic allocations. Apparently there are systems that violate that assumption because clang++ has a -fno-sane-operator-new switch, but I digress.) |
Sorry, something went wrong.
There was a problem hiding this comment.
Can you write this as sizeof(*data16)? EDIT: Here and in the other functions.
Sorry, something went wrong.
There was a problem hiding this comment.
Can you use sizeof(temp) in this block and the blocks below? LGTM apart from that.
Sorry, something went wrong.
|
Reviewers: fyi, the one change since Ben gave his LGTM was moving dst up a scope (out of if (IsBigEndian()) {}, back where it was originally. (And adding the test in the 2nd commit.) |
Sorry, something went wrong.
|
LGTM, thanks for @mentioning me! |
Sorry, something went wrong.
There was a problem hiding this comment.
Still LGTM but the commit logs should conform to the style guide.
Did you check what code paths clang and gcc emit? In the other PR, I had to prove that src == dst and had proper alignment before the compiler generated the fast case.
Sorry, something went wrong.
|
Fixed commit text.
Surprisingly it doesn't appear necessary to give those hints to the compilers in this incarnation for clang or gcc to emit bswap and nothing detrimental around it (https://godbolt.org/g/DxMNmF). The linux benchmarks from this PR match the BMs for #7644 as well (see #7645 (comment)). |
Sorry, something went wrong.
Sorry, something went wrong.
|
Is this CI situation normal or am I cursed?! |
Sorry, something went wrong.
|
Ahem, yes, let’s give this another shot: https://ci.nodejs.org/job/node-test-commit/5328/ (It is, unfortunately, normal and the act of complaining about the general brokenness of CI is part of what forms the common core collaborator identity. Welcome to the club! :b) |
Sorry, something went wrong.
There was a problem hiding this comment.
LGTM
Sorry, something went wrong.
|
More CI attempts needed to land? |
Sorry, something went wrong.
|
@zbjornson started new CI run: https://ci.nodejs.org/job/node-test-pull-request/4337/ |
Sorry, something went wrong.
|
Oh didn't notice that there is a conflict. |
Sorry, something went wrong.
Removes use of builtins that are unavailable for older clang. Per benchmarks, only uses builtins on Windows, where speedup is significant. Fixes: nodejs#7618
Between nodejs#3410 and nodejs#7645, bytes were swapped twice on bigendian platforms if buffer was not two-byte aligned. See comment in nodejs#7645.
Sorry, something went wrong.
Sorry, something went wrong.
|
🎉 7th time's a charm I guess :) |
Sorry, something went wrong.
|
Okay, I'm going to start landing this.
|
Sorry, something went wrong.
Removes use of builtins that are unavailable for older clang. Per benchmarks, only uses builtins on Windows, where speedup is significant. Also adds test for unaligned ucs2 buffer write. Between #3410 and #7645, bytes were swapped twice on bigendian platforms if buffer was not two-byte aligned. See comment in #7645. PR-URL: #7645 Fixes: #7618 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: James M Snell <jasnell@gmail.com>
|
landed in 7420835 , thanks a lot @zbjornson ! |
Sorry, something went wrong.
|
Concerning backporting, I guess this should be backported to wherever #7157 was backported, which is v6 but not v4. If anyone disagrees let me know. |
Sorry, something went wrong.
Removes use of builtins that are unavailable for older clang. Per benchmarks, only uses builtins on Windows, where speedup is significant. Also adds test for unaligned ucs2 buffer write. Between #3410 and #7645, bytes were swapped twice on bigendian platforms if buffer was not two-byte aligned. See comment in #7645. PR-URL: #7645 Fixes: #7618 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: James M Snell <jasnell@gmail.com>
Removes use of builtins that are unavailable for older clang. Per benchmarks, only uses builtins on Windows, where speedup is significant. Also adds test for unaligned ucs2 buffer write. Between #3410 and #7645, bytes were swapped twice on bigendian platforms if buffer was not two-byte aligned. See comment in #7645. PR-URL: #7645 Fixes: #7618 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: James M Snell <jasnell@gmail.com> Conflicts: src/node_buffer.cc
| Back | FazBrowse Home | New Git URL |
Fixes #7618
Alternative to #7644 that preserve performance.
Also consolidates all byte-swapping code (following what bnoordhuis did in #7644).