{"action":"created","issue":{"url":"https://api.github.com/repos/johnmccutchan/ecmascript_simd/issues/59","labels_url":"https://api.github.com/repos/johnmccutchan/ecmascript_simd/issues/59/labels{/name}","comments_url":"https://api.github.com/repos/johnmccutchan/ecmascript_simd/issues/59/comments","events_url":"https://api.github.com/repos/johnmccutchan/ecmascript_simd/issues/59/events","html_url":"https://github.com/johnmccutchan/ecmascript_simd/issues/59","id":42750295,"number":59,"title":"How will native code port on top of JS-SIMD?","user":{"login":"juj","id":225351,"avatar_url":"https://avatars.githubusercontent.com/u/225351?v=3","gravatar_id":"","url":"https://api.github.com/users/juj","html_url":"https://github.com/juj","followers_url":"https://api.github.com/users/juj/followers","following_url":"https://api.github.com/users/juj/following{/other_user}","gists_url":"https://api.github.com/users/juj/gists{/gist_id}","starred_url":"https://api.github.com/users/juj/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/juj/subscriptions","organizations_url":"https://api.github.com/users/juj/orgs","repos_url":"https://api.github.com/users/juj/repos","events_url":"https://api.github.com/users/juj/events{/privacy}","received_events_url":"https://api.github.com/users/juj/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":35,"created_at":"2014-09-15T08:26:38Z","updated_at":"2015-06-20T21:49:42Z","closed_at":null,"body":"With Emscripten, we have the capacity to port native C&C++ code to the web. When/if people read tweets along the lines of \"JS has SIMD\", it will invariably result in a stream of Emscripten developers attempting to port their MMX/SSE1/SSE2/... -based codebases over to JS-SIMD. We need to have an answer to these developers about what the support of mapping these constructs over to JS-SIMD looks like.\r\n\r\nIn the Emscripten compiler, we already have small bits of such SIMD support available. To chart what this mapping would look like for SSE1 in particular (focusing on just one instruction set spec to start with, and SSE1 is the most interesting one) when completed, I wrote up this spreadsheet: https://docs.google.com/spreadsheets/d/1QAGGf2M2IA6l4cvh8eTXdXGEUcPjdmTe_BLKGn5YCB4/edit?usp=sharing\r\n\r\nAs one can imagine, comparing the current spec and the set of SSE1 intrinsics listed in the above spreadsheet, there is a large gap. I wonder how this could be resolved?"},"comment":{"url":"https://api.github.com/repos/johnmccutchan/ecmascript_simd/issues/comments/113824806","html_url":"https://github.com/johnmccutchan/ecmascript_simd/issues/59#issuecomment-113824806","issue_url":"https://api.github.com/repos/johnmccutchan/ecmascript_simd/issues/59","id":113824806,"user":{"login":"juj","id":225351,"avatar_url":"https://avatars.githubusercontent.com/u/225351?v=3","gravatar_id":"","url":"https://api.github.com/users/juj","html_url":"https://github.com/juj","followers_url":"https://api.github.com/users/juj/followers","following_url":"https://api.github.com/users/juj/following{/other_user}","gists_url":"https://api.github.com/users/juj/gists{/gist_id}","starred_url":"https://api.github.com/users/juj/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/juj/subscriptions","organizations_url":"https://api.github.com/users/juj/orgs","repos_url":"https://api.github.com/users/juj/repos","events_url":"https://api.github.com/users/juj/events{/privacy}","received_events_url":"https://api.github.com/users/juj/received_events","type":"User","site_admin":false},"created_at":"2015-06-20T21:49:42Z","updated_at":"2015-06-20T21:49:42Z","body":"There's now been some progress in Emscripten with adding more SIMD support. Previously the SSE1 instruction set was already supported, and now there's a pull request that also adds SSE2 support ( https://github.com/kripken/emscripten-fastcomp/pull/103, https://github.com/kripken/emscripten/pull/3542 ). The implementation has been done against the v0.6 version of the SIMD.js spec at http://littledan.github.io/simd.html . Both SSE1 and SSE2 apis are supported fully (although not necessarily accelerated!), except for rounding modes, floating point exceptions, denormal handling and issues with certain patterns of NaN<->float interaction.\r\n\r\nQuantitatively measuring, the analysis is that current SIMD.js support allows native code to get the following:\r\n\r\n  - 38/95 (40.0%) of the intrinsics of SSE1 are expected to compile down to the direct native counterpart instruction.\r\n  - The same amount, 38/95 (40.0%) intrinsics of SSE1 need to be emulated as a sequence of other intrinsics in order to simulate the native hardware instruction that SIMD.js is not able to express.\r\n  - The remaining 19/95 (20.0%) instructions cannot be emulated as other SIMD.js intrinsics, but are implemented as a scalar fallback. One of these instructions, _mm_prefetch(), is not available and therefore a no-op.\r\n\r\nFor the SSE2 intrinsics set, the quantitative analysis is as follows:\r\n\r\n  - 101/207 (48.8%) of the intrinsics are expected to be in the fast path, and offer 1:1 the direct native counterpart.\r\n  - 48/207 (23.2%) of the intrinsics are sequences of other SIMD.js intrinsics in order to emulate the native SSE2 instruction.\r\n  - The remaining 58/207 (28.0%) intrinsics are not supported by SIMD.js, and a scalar fallback has been implemented instead. Of these, two intrinsics, _mm_clflush() and _mm_pause() are ignored as no-op operations.\r\n\r\nThe numbers are my estimates from tallying up the current implementations of the code in Emscripten's xmmintrin.h and emmintrin.h - they may be possible to improve. In total, SIMD.js supports 46.0% of native SSE1+SSE2 instructions.\r\n\r\nUnfortunately the internet does not much care about details, and/or the initial messaging was not handled in the best possible way when SIMD.js went public, and this turned into a binary \"SIMD is now supported\" message (e.g. http://www.reddit.com/r/programming/comments/1tv5ap/javascript_gains_support_for_simd/ ). For us, this has led to having to do some amount of expectation management with developers that we communicate with, since they are not aware that JavaScript does not really have direct access to the hardware SIMD instructions. In Emscripten we have added a new API of intrinsics that maps directly to the SIMD.js counterparts, but there has so far been very little interest from developers to hear about rewriting their SIMD code on top of a new meta-API that does not reflect to the hardware. The expectation seems to be that the SIMD port should be doable by switching (an existing) build flag, and if not, they will not care. For this reason, supporting the exact SSEx instruction sets with bit-to-bit correct behavior is the most important initial goal for SIMD in Emscripten.\r\n\r\nQualitatively, it is yet difficult to say if the coverage rates are large enough to provide a successful API to Emscripten developers, or for how many this will be a performance blocker. It is clear that running off the SIMD path to a scalar fallback will seriously hit performance, but the question is whether overall performance will still be a gain despite the presence of emulated instructions. Currently no browser yet supports enough of the v0.6 version of the SIMD.js to run SSE2, and they fall back to the polyfill. For example, Firefox does not yet have the int8x16, int16x8 and float64x2 types, and hence SSE2 code does not validate as asm.js, so I do not yet have benchmark numbers of how good SSE2 performance is on an \"average\" codebase (whatever that might mean).\r\n\r\nWe have already seen most companies come up with their easy (e.g. from perspective to being even autovectorized) SSE1 Mandelbrot tests, and in those, there is an easily achievable performance gain. That does not yet validate the SIMD.js API as a mature spec, but rather it will be the variety of projects that SIMD.js can cater to that will. More complex codecs, image processing libraries and similar are not sufficient with SSE1 only, so now that Emscripten and browser support matures, we are looking to benchmark more complex projects for better experience of how useful SIMD.js already is.\r\n\r\nI think that the current SIMD.js spec will be useful for the most linear algebra game math libraries, and game physics engines, that map quite straightforwardly to the float32x4/float64x2 add/sub/mul/div/shuffle ops and don't need much else (and certainly never see nans or infs). Most likely it will be the codebases where developers have really gotten creative in their uses of SSE, abusing the nonsymmetry of the various operations, NaN behavior and propagation, and masking, that are likely to cause headache. NaN canonicalization (in the SIMD<->float boundary) seems to be the number one blocker, since it breaks correctness across the board in different code patterns, though it might be possible to come up with a set of rules and conventions on what kind of code people should be looking out for that will not work in JS. Also the lack of controllable rounding modes might be an issue to some projects.\r\n\r\nNevertheless, I feel quite happy that the SSE1 and SSE2 support code in Emscripten is even in such a good shape that it already is. At first I thought that it would not be possible to support nearly as much of SSE2 that it is, so great job with the spec there! I'm looking forward to seeing more discussion about the SIMD.universe and perhaps in the future with WebAssembly, that might improve the coverage rates for native SSE instructions.\r\n"}}