[dev-servo] Recent Improvements to Functions like getClientBoundingRect

2014-08-28 Thread Clark Gaebel
Hi servo-dev!

Servo exists to validate the idea that parallel browser architectures work. 
Going parallel isn't always a good thing, and can sometimes be worse if there's 
too much communication overhead. For example, in the current Servo design, 
javascript is run in a different task than layout. This is great, but it means 
that javascript calls that require communication between the tasks can incur a 
lot of overhead.

Consider this HTML/JS:

html
script

var ready = function() {
var ident = document.getElementById(some_div);
var left_sum = 0;
var top_sum = 0;
var right_sum = 0;
var bottom_sum = 0;
var t0 = +new Date();
for(var i = 0; i  1000; i++) {
  var rect = ident.getBoundingClientRect();
  left_sum   += rect.left;
  top_sum+= rect.top;
  right_sum  += rect.right;
  bottom_sum += rect.bottom;
}
var t1 = +new Date();

ident.appendChild(document.createTextNode(sums: ( + left_sum + ,  + top_sum 
+ ,  + right_sum + ,  + bottom_sum + ) ));
ident.appendChild(document.createTextNode(dt:  + (t1 - t0) +  ms));
}

//document.addEventListener(DOMContentLoaded, ready, false)
window.onload = ready;
/script
body
div id=some_divWorking.../div
/body
/html

Running this on Firefox takes 500 ns/iteration. Chrome takes 700 ns/iteration.

Servo before [1] lands took 8100 ns! That's paying a lot (some would say too 
much) for a parallel architecture, when simple queries experience a 10x 
slowdown.

However, thanks to [1], Servo is down to 950 ns/iteration. This is very 
competitive with Firefox and Chrome, especially when considering the mutex 
involved. I'm sure with some micro-optimization work we can get closer.

Because of these results, I believe that communication overhead between script 
and layout can be (and has been) reduced to a competitive amount, while still 
maintaining the benefits of parallelization.

Regards,
  - Clark

[1] https://github.com/servo/servo/pull/3164
___
dev-servo mailing list
dev-servo@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-servo


Re: [dev-servo] Recent Improvements to Functions like getClientBoundingRect

2014-08-28 Thread Patrick Walton

On 8/28/14 5:56 PM, Cameron Zwarich wrote:

It’s nice that it’s so close to the competition. It would be interesting to see 
numbers on ARM as well, since the relative cost of the atomic instructions 
might be higher, even in the uncontended case.

Is it strictly enforced that the script task never sees inconsistent views of 
layout? This came up in the other thread about threading, but what prevents 
this incorrect scenario?

1) The script task takes the mutex to access one property of layout.
2) The script task releases the mutex.
3) Layout changes the property that was accessed.
4) The script task takes the mutex again to access the same property, in the 
same turn of the event loop without modifying layout in any intervening work 
since the last attempt.
5) The script task reads a different value from before.


Doh. I wonder if we should just keep the mutex held until the next turn 
of the event loop (though don't take it at the outset until the moment 
script starts reading back from layout).


This is actually even better for Clark's benchmark, as it reduces the 
number of atomic operations in the tight loop to O(1) from O(n).


Patrick

___
dev-servo mailing list
dev-servo@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-servo


Re: [dev-servo] Recent Improvements to Functions like getClientBoundingRect

2014-08-28 Thread Cameron Zwarich
On Aug 28, 2014, at 6:00 PM, Patrick Walton pcwal...@mozilla.com wrote:

 On 8/28/14 5:56 PM, Cameron Zwarich wrote:
 It’s nice that it’s so close to the competition. It would be interesting to 
 see numbers on ARM as well, since the relative cost of the atomic 
 instructions might be higher, even in the uncontended case.
 
 Is it strictly enforced that the script task never sees inconsistent views 
 of layout? This came up in the other thread about threading, but what 
 prevents this incorrect scenario?
 
 1) The script task takes the mutex to access one property of layout.
 2) The script task releases the mutex.
 3) Layout changes the property that was accessed.
 4) The script task takes the mutex again to access the same property, in the 
 same turn of the event loop without modifying layout in any intervening work 
 since the last attempt.
 5) The script task reads a different value from before.
 
 Doh. I wonder if we should just keep the mutex held until the next turn of 
 the event loop (though don't take it at the outset until the moment script 
 starts reading back from layout).
 
 This is actually even better for Clark's benchmark, as it reduces the number 
 of atomic operations in the tight loop to O(1) from O(n).

I assumed that was the case, but was going to wait for his response before the 
obvious follow-up question. We did a similar thing with iOS WebKit: a recursive 
mutex that was only released on the turn of an event loop. It was universally 
regarded as being a terrible idea, but nobody had a better solution.

This does mean that we get little-to-no parallelism with things like 
interactive touch event processing, but that might just be impossible with the 
web as-is.

Cameron
___
dev-servo mailing list
dev-servo@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-servo


Re: [dev-servo] Recent Improvements to Functions like getClientBoundingRect

2014-08-28 Thread Cameron Zwarich
Do such events always cause the layout task to require DOM access to create the 
flow tree? If so, the layout task would still have to wait for the script task 
to finish, meaning that layout still can’t occur unless forced by script.

Cameron

On Aug 28, 2014, at 7:10 PM, Patrick Walton pwal...@mozilla.com wrote:

 It might happen if layout is flushed from outside the script task; window 
 resizing/device rotation being what immediately comes to mind, as today in 
 Servo those events go straight from compositor to layout without hitting the 
 script task at all. (As an alternative design, we could route such events 
 through the script task; this would remove the necessity of the mutex but 
 would block layout for such events if script is running, even if the script 
 hasn't touched the DOM.)
 
 Patrick
 
 On August 28, 2014 7:05:09 PM PDT, Robert O'Callahan rob...@ocallahan.org 
 wrote:
 On Fri, Aug 29, 2014 at 12:56 PM, Cameron Zwarich zwar...@mozilla.com
 wrote:
 
  Is it strictly enforced that the script task never sees inconsistent views
  of layout? This came up in the other thread about threading, but what
  prevents this incorrect scenario?
 
  1) The script task takes the mutex to access one property of layout.
  2) The script task releases the mutex.
  3) Layout changes the property that was accessed.
  4) The script task takes the mutex again to access the same property, in
  the same turn of the event loop without modifying layout in any intervening
  work since the last attempt.
  5) The script task reads a different value from before.
 
 
 I'm confused. Before or during step 1, the layout must be brought up to
 date (flushed, in Gecko
 parlance). So step 3 shouldn't happen since layout
 would already be fully up to date.
 
 Rob
 
 -- 
 Sent from my Android phone with K-9 Mail. Please excuse my brevity.

___
dev-servo mailing list
dev-servo@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-servo


Re: [dev-servo] Recent Improvements to Functions like getClientBoundingRect

2014-08-28 Thread Robert O'Callahan
On Fri, Aug 29, 2014 at 2:10 PM, Patrick Walton pwal...@mozilla.com wrote:

 It might happen if layout is flushed from outside the script task; window
 resizing/device rotation being what immediately comes to mind, as today in
 Servo those events go straight from compositor to layout without hitting
 the script task at all. (As an alternative design, we could route such
 events through the script task; this would remove the necessity of the
 mutex but would block layout for such events if script is running, even if
 the script hasn't touched the DOM.)


Hmm. So given

var v = e.getBoundingClientRect();
// layout change is triggered by window resizing or whatever
var v2 = e.getBoundingClientRect();

what in Servo, prior to Clark's work, ensures v and v2 are the same?

Rob
-- 
oIo otoeololo oyooouo otohoaoto oaonoyooonoeo owohooo oioso oaonogoroyo
owoiotoho oao oboroootohoeoro oooro osoiosotoeoro owoiololo oboeo
osouobojoeocoto otooo ojouodogomoeonoto.o oAogoaoiono,o oaonoyooonoeo
owohooo
osoaoyoso otooo oao oboroootohoeoro oooro osoiosotoeoro,o o‘oRoaocoao,o’o
oioso
oaonosowoeoroaoboloeo otooo otohoeo ocooouoroto.o oAonodo oaonoyooonoeo
owohooo
osoaoyoso,o o‘oYooouo ofolo!o’o owoiololo oboeo oiono odoaonogoeoro
ooofo
otohoeo ofoioroeo ooofo ohoeololo.
___
dev-servo mailing list
dev-servo@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-servo


Re: [dev-servo] Recent Improvements to Functions like getClientBoundingRect

2014-08-28 Thread Patrick Walton
I believe the answer today is nothing--i.e. it's a Servo bug. Clark's work 
doubles as a nice way to fix it :)

Patrick

On August 28, 2014 7:18:27 PM PDT, Robert O'Callahan rob...@ocallahan.org 
wrote:
On Fri, Aug 29, 2014 at 2:10 PM, Patrick Walton pwal...@mozilla.com
wrote:

 It might happen if layout is flushed from outside the script task;
window
 resizing/device rotation being what immediately comes to mind, as
today in
 Servo those events go straight from compositor to layout without
hitting
 the script task at all. (As an alternative design, we could route
such
 events through the script task; this would remove the necessity of
the
 mutex but would block layout for such events if script is running,
even if
 the script hasn't touched the DOM.)


Hmm. So given

var v = e.getBoundingClientRect();
// layout change is triggered by window resizing or whatever
var v2 = e.getBoundingClientRect();

what in Servo, prior to Clark's work, ensures v and v2 are the same?

Rob
-- 
oIo otoeololo oyooouo otohoaoto oaonoyooonoeo owohooo oioso oaonogoroyo
owoiotoho oao oboroootohoeoro oooro osoiosotoeoro owoiololo oboeo
osouobojoeocoto otooo ojouodogomoeonoto.o oAogoaoiono,o oaonoyooonoeo
owohooo
osoaoyoso otooo oao oboroootohoeoro oooro osoiosotoeoro,o
o‘oRoaocoao,o’o
oioso
oaonosowoeoroaoboloeo otooo otohoeo ocooouoroto.o oAonodo oaonoyooonoeo
owohooo
osoaoyoso,o o‘oYooouo ofolo!o’o owoiololo oboeo oiono odoaonogoeoro
ooofo
otohoeo ofoioroeo ooofo ohoeololo.

-- 
Sent from my Android phone with K-9 Mail. Please excuse my brevity.
___
dev-servo mailing list
dev-servo@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-servo


Re: [dev-servo] Recent Improvements to Functions like getClientBoundingRect

2014-08-28 Thread Cameron Zwarich
On Aug 28, 2014, at 5:45 PM, Clark Gaebel cgae...@mozilla.com wrote:

 Running this on Firefox takes 500 ns/iteration. Chrome takes 700 ns/iteration.
 
 Servo before [1] lands took 8100 ns! That's paying a lot (some would say too 
 much) for a parallel architecture, when simple queries experience a 10x 
 slowdown.
 
 However, thanks to [1], Servo is down to 950 ns/iteration. This is very 
 competitive with Firefox and Chrome, especially when considering the mutex 
 involved. I'm sure with some micro-optimization work we can get closer.

As a side point, why is there a 7 us overhead here for message-passing between 
green threads? Is it really that bad? Are script and layout currently green 
tasks, or did something land causing this to not be the case?

Cameron
___
dev-servo mailing list
dev-servo@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-servo