5 ms·
You know, I'm not entirely sure how I feel about this. On the one hand: yeah, I get that having really multithreaded stuff is pretty handy, especially for certa
by pfooti 10y ago
You know, I'm not entirely sure how I feel about this. On the one hand: yeah, I get that having really multithreaded stuff is pretty handy, especially for certain computationally-bound tasks.
On the other hand, I quite like the single-threadedness of javascript. Promises-based systems (or async/await) give us basically cooperative multitasking anyway to break up long-running (unresponsive) threads without worrying about mutexes and semaphores. I understand exactly when and where my javascript code will be interrupted, and I don't need to wrap blocks in atomic operation markers extraneously.
I've written plenty multithreaded code, starting with old pthreads stuff and eventually moving on to Java (but my own experience with threaded stuff is limited mainly to C and Java), and it can be a real pain. I guess limiting shared memory to explicitly named blocks means you don't have as much to worry about vis-a-vis nonreentrant code messing up your memory space.
That said, it is a pretty useful construct, and I see where this can benefit browser-based games dev in particular (graphics can be sped up a lot with multicore rendering, I bet).
- ihsw 10y agoWelp, the idea is portability. This is a bridge between other platforms into JS, and -- as you mentioned -- its usage is largely specialized. Most people don't really know what typed arrays are, but they're in ES6 nevertheless.
- deleted 10y ago[deleted]
- zzzcpan 10y ago> I understand exactly when and where my javascript code will be interrupted That's why callbacks, promises, async/await and all that are neither multitasking, nor multithreading. They are all about control, while multithreading is all about parallelism and is essentially a very low-level specialized thing, that nobody should be using, unless absolutely necessary.
- pfooti 10y agoWell, I'm old enough to remember coding for Mac OS 8, where "multitasking" was indeed cooperative - I had to say "oh, you can interrupt me here, if you want" at different places in my code, which meant bad actors could lock the system of course. It wasn't great. On the other hand, in the uncommon event I do have some weird javascript thing that's going to take a long time (say, parsing some ridiculously-big JSON blob to build a dashboard or something), I know I can break up my parse into promises for each phase and that I won't be locking up other UI processing as badly during that process. So: not exactly multitasking / threading as you say, but still a handy thing to think about.
- spenuke 10y agoI'm still totally ignorant of the new primitives in the original link, so maybe that's why I'm confused, but: are you saying that as of today, wrapping a big parsing job into a promise frees up the event loop? I really don't think that's the case, is it? JSON.parse is gonna be blocking/synchronous whenever it happens. Can you explain a bit more of the implementation you're describing?
- pfooti 10y agoNot the parsing part, but the processing part. Assume I've got a big pile of data and am calculating stuff like correlations on it. If I break the process up into chunks, I can go chunk.then(nextChunk).then(afterThat) etc etc. JSON.parse still blocks, but it's the post-processing I'm talking about.
- roblabla 10y agoYou can use setTimeout to "free up the event loop". Using setTimeout(fun, 0) will run fun after the event loop has been freed up IIRC. NodeJS has a function called setImmediate that does exactly that. JSON.parse as implemented is going to be blocking. But it's possible to implement an asynchronous, non-blocking JSON parser See also : http://stackoverflow.com/questions/779379/why-is-settimeoutfn-0-sometimes-useful http://stackoverflow.com/questions/779379/why-is-settimeoutf... Edit : requestAnimationFrame is a better alternative to setTimeout(fun, 0), as it allows the browser to update the UI.
- chrisseaton 10y ago> multithreading is all about parallelism This just isn't true. Why do you think people wrote multi-threaded applications back when almost all machines had just one processor and just one core? Threads give you concurrency as well, even if you don't want or need parallelism.
- rubiquity 10y agoGreat point. I find myself reminding people about this all too often.
- nly 10y agoExactly. Threading actually enables a simple asynchronous blocking programming model through locks (at the expense of introducing loads of potential locking hazards).
- zzzcpan 10y agoBlocking presumes synchronicity. Locks are by definition synchronization primitives.
- zzzcpan 10y agoOf course they do. Anything can give you concurrency. But pretty much anything can make concurrency easier, than threads. > Why do you think people wrote multi-threaded applications back when almost all machines had just one processor and just one core? Almost none did. Popular networking servers were either preforking, forking or asynchronous. Desktop GUIs were event driven. Threads weren't even very usable on most systems at that time, i.e. up until a decade and a half ago or so, weren't they?
- chrisseaton 10y agoThreads weren't very usable on most systems until around 2001? No, I don't know where you've got that idea from but it's not the case. Java had threads in 1996. The Windows 32 API had threads from at least Windows 95. Windows NT had them since 1993. I don't know when Linux got threads and couldn't find anything, but I would presume it was the mid 90s at the very latest. In fact I don't think any of these threading APIs will have even changed much since the mid 90s. They weren't new ideas at the time either! Look at this thread programming manual from 1994 which on page 3 lists five benefits of using threads at the time, only one of which is utilising the relatively rare multiprocessors. http://www4.ncsu.edu/~rhee/clas/csc495j/MultithreadedProgrammingGuide_Solaris24.pdf http://www4.ncsu.edu/~rhee/clas/csc495j/MultithreadedProgram...
- Sanddancer 10y agoI disagree that parallelism is inherently a low-level specialized thing. There are a lot of operations, like handling any sort of media, that are naturally parallel. If I'm parsing through an image file, I know exactly where it begins and ends, and with very few bits that are dependent on other bits, it just makes sense to be able to spread that operation through the many cores that exist in a modern machine.
- CiPHPerCoder 10y agoA multi-threaded JavaScript also means this becomes more troubling: https://github.com/nodejs/node/issues/5798 https://github.com/nodejs/node/issues/5798 Node.js uses OpenSSL instead of the operating system's CSPRNG. The biggest argument for "WONTFIX" is "Node.js is single-threaded so OpenSSL fork-unsafety isn't a concern for us". If JavaScript becomes multi-threaded, it's not unreasonable to expect Node.js to follow. If it does follow, expect random numbers to repeat because of OpenSSL's broken RNG.
- atoponce 10y agoMeh. Operating system CSPRNGs can be slow, whereas userspace CSPRNGs seeded from the OS CSPRNG can be fast, fast, fast. Explain how the OpenSSL RNG is broken, and why it's a bad idea to rely on it.
- CiPHPerCoder 10y agoThat's explained in painstaking detail in the Github issue I linked to.
- atoponce 10y agoOkay. I read the whole thread (ugh). Arguments for using the kernelspace CSPRNG basically boils down to this: 1. Kernelspace CSPRNGs generally don't change, are well audited, and are generally accepted to be secure. 2. Userspace CSPRNGs don't provide any additional security benefit. 3. OpenSSL is a questionable security product with it's history of vulnerabilities. So, with that said, let's look at each of them. For the first point, I don't fully agree. The Linux kernel CSPRNG has changed from MD5 based to SHA-1 based. I have heard chatter (I don't have a source to cite this) that it should move to SHA-256 with the recent collision threats of SHA-1. There is also a separate movement to standardize it on NIST DRBG designs (CTR_DRBG, Hash_DRBG, HMAC_DRBG- https://lkml.org/lkml/2016/4/24/28 https://lkml.org/lkml/2016/4/24/28). Starting with Windows Vista, Microsoft changed their CSPRNG to FIPS 186-2 or NIST SP 800-90A (depending on Windows version), which could be hash-based or AES counter based. OpenBSD changed from using Yarrow and arcfour to ChaCha20. So, no, kernelspace CSPRNGs change all the time. For the second point, I greatly disagree. First, you need a specific RNG to compare to. It's considered "unsafe" to use MD5 as a CSPRNG, although that would require pre-image attacks on MD5, of which it still remains secure. Additionally, a userspace AES-256-CTR_DRBG is theoretically more secure than an AES-128-CTR_DRBG design. While that matters little it terms of practical use, the reality is that AES-256 has a larger security margin than AES-128, as I understand it. Same for using SHA-256-Hash_DRBG instead of SHA-1-Hash_DRBG. Userspace CSPRNGs can be more secure than kernelspace. Finally, as far as I know, attacks on OpenSSL have been overwhelmingly CBC padding oracle attacks, in one form or another. There have been a couple RNG vulnerabilities with OpenSSL (https://www.openssl.org/news/vulnerabilities.html https://www.openssl.org/news/vulnerabilities.html), but same with say the Linux RNG (https://github.com/torvalds/linux/commit/19acc77a36970958a4a0e4daeb2c8cb2aab0ffd4 https://github.com/torvalds/linux/commit/19acc77a36970958a4a...). So, I'm not sure this is a valid point. The biggest reason why you should use a userspace CSPRNG is performance. System RNGs generally suck. The Linux kernel can't get much faster than about 15-20 MiBps. Similarly with Mac OS X and FreeBSD. OpenBSD can get about 80 MiBps (on testing with similar hardware), but that's just painful for a single host trying to serve up HTTPS websites, when the HDD (nevermind SSDs) can read data off at 100 MiBps without much problem. The kernelspace CSPRNG can't even keep up with disk IO. Userspace CSPRNGs can get into 200-300 MiBps without much problem, and with AES-NI (provided that you're using AES-128-CTR_DRBG), 2 GiBps (https://pthree.org/2016/03/08/linux-kernel-csprng-performance/ https://pthree.org/2016/03/08/linux-kernel-csprng-performanc...). But, I do agree with one very serious concern on using userspace RNGs in general: they can introduce bugs and vulnerabilities that don't exist with the system CSPRNG. Expecting a developer to get this right, especially one who is not familiar with cryptographic pitfalls, can be a massive challenge. But this isn't the case with the OpenSSL RNG. So, I guess I don't see the point to move the node.js CSPRNG dependency from OpenSSL to kernelspace.
- daveroberts 10y agoI know very little about the subject, but when multi-core processors were first introduced, I remember that the general wisdom was that server software could benefit, from its highly concurrent nature, but games and graphics would not, because they are generally single threaded. I wonder if the general wisdom at the time was wrong, or if there has been a big shift to take advantage of multiple cores. I'm guessing the later.
- dherman 10y ago[I'm a colleague of the OP and Mozilla/TC39 member, i.e. someone who cares a lot about the JS programming model :)] I'm enthusiastic about SharedArrayBuffer because, unlike threads in traditional languages like C++ or Java, we have two separate sets of tools for two very separate jobs: workers and shared memory for _parallelism_, and async functions and promises for _concurrency_. Not to put too fine a point on it, shared memory primitives are critical building blocks for unlocking some of the highest performance use cases of the Web platform, particularly for making full use of multicore and hyperthreaded hardware. There's real power the Web has so far left on the table, and it's got the capacity to unleash all sorts of new classes of applications. At the same time, I _don't_ believe shared memory should, or in practice will, change JavaScript's model of concurrency, that is, handling simultaneous events caused by e.g. user interface actions, timers, or I/O. In fact, I'm extremely excited about where JavaScript is headed with async functions. Async functions are a sweet spot between on the one hand the excessively verbose and error-prone world of callbacks or often even hand-written promise-based control flow and on the other hand the fully implicit and hard-to-manage world of shared-memory threading. The async culture of JS is strong and I don't see it being threatened by a low-level API for shared binary data. But I do see it being a primitive that the JS ecosystem can use to experiment with parallel programming models.
- pfooti 10y agoYes, the thing I in particular worry about is the event dispatch system. The last thing we need there is multithreaded event dispatch, where multiple handlers fire at the same time, possibly resulting in race conditions on state managing objects. But on closer inspection of the post, this implementation seems to be highly targeted at certain kinds of compute-bound tasks, with just the shared byte array based memory. It's well-partitioned from the trad ui / network event processing system in a way that makes me optimistic about the language.
- finishingmove 10y agoAs someone who doesn't know much about how parallelism primitives are implemented, I need to ask why SharedArrayBuffer needs a length to be specified? From my layman viewpoint, this seems too low-level to be used for casual everyday applications.
- snissn 10y ago> On the other hand, I quite like the single-threadedness of javascript. Douglas Crockford's strategy of taking a language, identifying a subset of it, calling it "The Good Parts" and sticking to it is a great motivation to welcome new features, let them evolve but keep your distance from them until they're fleshed out. This has pretty much been the M.O. of Javascript and IMO has worked great..
- HappyTypist 10y agoMaybe for your standard web app, but try porting Unity or Unreal Engine over without better parallelism.