[whatwg] WebWorkers and images

On 1/13/11 4:37 PM, Glenn Maynard wrote:
> - trying to actually get very short, accurate timers, and
> - using timers simply to return to the browser, run any pending UI
> events, and then immediately start work again with no additional
> delay.

The second one is actually really really hard to do with setTimeout. 
Especially if you have UI events that need more than one trip through 
the event loop to do their thing.

> You don't need any trickery to get the latter

I'm not sure what you mean by "trickery" here.

>> The current spec draft says the floor is 4ms.
>
> I strongly disagree with this.  Browsers should be allowed to permit
> 0ms "return, run events then run this code immediately" timers.  It
> takes some heuristics to do this safely, to prevent code which
> (usually accidentally) assumes a minimum delay from busy looping, but
> browsers should be free to attempt such a heuristic, not required by
> spec to clamp to 4ms.

I oversimplified the spec a bit, for simplicity, because the main issue 
is in fact the clamped timers and what to clamp to and how to do it. 
The spec specifies a heuristic to use in just such a way, in fact.  I 
suggest you just read it if you're interested in the details....

> Timeouts in workers shouldn't require this, either, since there's no
> legacy code to worry about.

timeouts in workers are... weird as currently specced.  Not only do they 
have the 4ms floor for nested timeouts, but they're not specced in terms 
of wall-clock time but rather in terms of time during which the worker 
is not suspended.

>> Then it needs to be something that passes the object and _forgets_ it on the
>> caller side.
>
> For code that renders an entire scene at a time and displays it (most
> typical double-buffered OpenGL-like rendering), this might be useful,
> but I'm not sure it helps here.  He's incrementally rendering the
> result, so he needs to keep a copy of it to continue rendering the
> scene.

Who's incrementally rendering what?

The idea with the forgets approach would be that you have an imagedata 
object.  You pass it to the worker, the worker modifies it and passes it 
back.  The only constraint is that you can't touch the object while the 
worker is modifying it.  That seems like a pretty common use case.  Are 
we talking about some other use case here?

> I suspect there's something simpler going on here, though--as you
> said, copying a 10 MB buffer really should be very quick.

It's really not that quick, actually.  First, you have to allocate a new 
10MB buffer.  Then you have to memcpy into it.  Then you have to free it 
at some point.  I just wrote a simple test C program that has a single 
10MB array initialized and then in a loop allocates a 10MB array, 
memcpys into it, and then frees the 10MB allocation it just made.  It 
takes about 5ms per loop iteration to run on my system (fairly high-end 
laptop that was new in July 2010).  The time is split about 50-50 
between the allocation and the memcpy.

Just to be clear, 2.5ms to copy 10MB means that my CPU is spending about 
0.25ns per byte.  It's a 2.66Ghz CPU, so that's about 0.66 clock cycles 
per byte, or about 1.5 bytes per clock cycle.  That's pretty believable 
if we're having to stall the CPU every so often to wait for RAM.

Note that a key issue here is that 10MB is larger than half my L3 cache. 
  If I stick to arrays that are small enough that both source and 
destination fit in the cache, things are much faster.

> I think there's also another problem: he's drawing the image, and
> rendering the image incrementally as he goes.  To do that from a
> worker, you'd need to keep sending the ImageData in a message to the
> UI thread to display it.

Yes, indeed.

> That leads to a problem: how fast do you send it?  postMessage doesn't
> wait for messages to be received; if the worker doesn't know that the
> UI thread has actually received and processed the message, it won't
> know whether it should send a new message yet.  If it simply sends
> messages periodically, it may send them faster than the UI thread is
> taking them, queuing up a bunch of messages containing huge payloads.

If there's only one imagedata around, then the worker would send it to 
the ui thread, then have to wait till it got it back to do more painting 
to it.  But yes, I agree that this case is a bit more of a pain than the 
"here's an image, go do some expensive work on it and tell me when 
you're done" case.

> This seems like another important class of use cases for the
> "synchronously handling events" thread on webapps.

Quite possibly, yes.

-Boris

Received on Thursday, 13 January 2011 14:21:03 UTC