[HN Gopher] Exploring SIMD performance improvements in WebAssemb...
___________________________________________________________________
Exploring SIMD performance improvements in WebAssembly (2021)
Author : hackthesystem
Score : 49 points
Date : 2022-02-02 18:06 UTC (4 hours ago)
(HTM) web link (www.awelm.com)
(TXT) w3m dump (www.awelm.com)
| fwsgonzo wrote:
| I compared against native: #define ITERATIONS
| 1000 int main() { const size_t
| BUFFER_SIZE = 64ul \* 1024 \* 1024; __m128i\* data_buffer
| = (__m128i *)memalign(64, BUFFER_SIZE); const
| __m128i all_ones = _mm_set1_epi8(0xFF); for (size_t
| i = 0; i < ITERATIONS; i++) { __m128i* data =
| data_buffer; for (size_t b = 0; b < BUFFER_SIZE;) {
| _mm_stream_si128(&data[0], all_ones);
| _mm_stream_si128(&data[1], all_ones);
| _mm_stream_si128(&data[2], all_ones);
| _mm_stream_si128(&data[3], all_ones); data += 4;
| b += 16 * 4; } } } $ time
| ./fill_buffer.elf real 0m1,832s $ time
| ./wasmer fill_buffer.wasm -i fillBufferWithSIMD 1000 real
| 0m4,237s
|
| I had to fixup the WAT because set_local and get_local don't
| exist anymore. They are called local.get and local.set now.
|
| At higher number of iterations the C version converges on about
| 1.7 seconds per 1000, while the WASM version seems to remain the
| same at 4.2 secs per 1000. This leaves native 2.5x faster for
| this particular operation, on my machine.
| akireu wrote:
| It looks promising! But fixed-width lanes don't seem too cross-
| platform? I don't just mean the v256 and v512 types that may
| become ubiquitous in a few years, but also things like optimizing
| for different L1 cache sizes, doing some operation macro-fusion
| on the SIMD unit, or directly supporting leading/trailing
| elements to reduce code size?
| kevingadd wrote:
| In practice it's not possible to optimize "generally" for all
| possible target architectures your wasm will run on. You're
| going to optimize for x86-64 or ARM, and probably going to
| specifically optimize for modern intel, modern amd, or apple's
| m1. If you try to optimize for everything you're going to run
| into really painful tradeoffs and probably have mediocre
| performance on a bunch of architectures after a lot of hard
| work.
| akireu wrote:
| Why not? Fixed-size SIMD architectures use mostly the same
| operations, so if you target SSE2 initially, the code should
| run just fine on NEON. A runtime that ships a JIT compiler
| also has the unique opportunity to further optimize SIMD code
| by using more lanes or limiting the working set to the host
| platform's L1 cache size. Even the AOT compilers like GCC or
| clang emulate platform-specific intrinsics using generic
| vector ones. This should count for something, no?
| TinkersW wrote:
| They are similar but not the same, for instance SSE has
| movemask, but NEON does not, so it gets emulated(slowly)
| when targeting that platform. The cross lane ops are
| different enough that you might need to rewrite for other
| platforms. And then you run into situations where an
| instruction is very fast on one architecture but horribly
| slow on another because its basically emulated.
| hackthesystem wrote:
| Thanks! Good points, I think in general the fixed-width
| "packed" SIMD ISAs have the downsides that you mentioned.
|
| But it seems that WebAssembly doesn't have length-agnostic SIMD
| instructions yet. There is an open proposal to add this though:
| https://github.com/WebAssembly/flexible-vectors
| akireu wrote:
| Did a similar test in plain C: https://godbolt.org/z/ffYcWhxz3
| It's not quite the same: I've used an increment instead of
| zeroing, otherwise the entire benchmark gets optimized away.
| Still got just about the same result (3.7x speedup for 100
| iterations), so wasm did good there. Actually, now that I think
| of it, SIMD code performance probably depends on good register
| allocation more than on any optimization.
| nyanpasu64 wrote:
| I wonder if the 4x performance boost of 128-bit SIMD over 32-bit
| would drop to 2x if WebAssembly added 64-bit
| registers/instructions.
| hackthesystem wrote:
| I actually tried comparing 128-bit SIMD to the 64-bit
| performance and the difference was 2x. I only published the
| results for the 4x comparison, but it should be pretty easy to
| reproduce if you change the types in the non-SIMD code[1] from
| i32 -> i64.
|
| [1] https://github.com/awelm/simd-wasm-
| profiling/blob/master/fil...
| nynx wrote:
| Webassembly has 64-bit locals and instructions.
___________________________________________________________________
(page generated 2022-02-02 23:01 UTC)