New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use rayon to drive parallel layout and styling. #13641
Merged
+134
−525
Merged
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.
style: Use rayon instead of our custom work queue.
- Loading branch information
emilio
committed
Nov 14, 2016
commit 73917cce83d2225b51b29c374d861d71ec69435f
Unverified
This user has not uploaded their public key yet.
GPG key ID: 056B727BB9C1027C
Learn about signing commits
| @@ -12,12 +12,11 @@ use context::{LayoutContext, SharedLayoutContext}; | ||
| use flow::{self, Flow, MutableFlowUtils, PostorderFlowTraversal, PreorderFlowTraversal}; | ||
| use flow_ref::FlowRef; | ||
| use profile_traits::time::{self, TimerMetadata, profile}; | ||
| use rayon; | ||
| use std::mem; | ||
| use std::sync::atomic::{AtomicIsize, Ordering}; | ||
| use style::dom::UnsafeNode; | ||
| use style::parallel::{CHUNK_SIZE, WorkQueueData}; | ||
| use style::parallel::run_queue_with_custom_work_data_type; | ||
| use style::workqueue::{WorkQueue, WorkUnit, WorkerProxy}; | ||
| use style::parallel::CHUNK_SIZE; | ||
| use traversal::{AssignISizes, BubbleISizes}; | ||
| use traversal::AssignBSizes; | ||
| use util::opts; | ||
| @@ -50,10 +49,8 @@ pub fn borrowed_flow_to_unsafe_flow(flow: &Flow) -> UnsafeFlow { | ||
| } | ||
| } | ||
|
|
||
| pub type UnsafeFlowList = (Box<Vec<UnsafeNode>>, usize); | ||
|
|
||
| pub type ChunkedFlowTraversalFunction = | ||
| extern "Rust" fn(UnsafeFlowList, &mut WorkerProxy<SharedLayoutContext, UnsafeFlowList>); | ||
| pub type ChunkedFlowTraversalFunction<'scope> = | ||
| extern "Rust" fn(Box<[UnsafeFlow]>, &'scope SharedLayoutContext, &rayon::Scope<'scope>); | ||
|
|
||
| pub type FlowTraversalFunction = extern "Rust" fn(UnsafeFlow, &SharedLayoutContext); | ||
|
|
||
| @@ -133,27 +130,35 @@ trait ParallelPostorderFlowTraversal : PostorderFlowTraversal { | ||
|
|
||
| /// A parallel top-down flow traversal. | ||
| trait ParallelPreorderFlowTraversal : PreorderFlowTraversal { | ||
| fn run_parallel(&self, | ||
| unsafe_flows: UnsafeFlowList, | ||
| proxy: &mut WorkerProxy<SharedLayoutContext, UnsafeFlowList>); | ||
| fn run_parallel<'scope>(&self, | ||
| unsafe_flows: &[UnsafeFlow], | ||
| layout_context: &'scope SharedLayoutContext, | ||
| scope: &rayon::Scope<'scope>); | ||
|
|
||
| fn should_record_thread_ids(&self) -> bool; | ||
|
|
||
| #[inline(always)] | ||
| fn run_parallel_helper(&self, | ||
| unsafe_flows: UnsafeFlowList, | ||
| proxy: &mut WorkerProxy<SharedLayoutContext, UnsafeFlowList>, | ||
| top_down_func: ChunkedFlowTraversalFunction, | ||
| bottom_up_func: FlowTraversalFunction) { | ||
| let mut discovered_child_flows = Vec::new(); | ||
| for unsafe_flow in *unsafe_flows.0 { | ||
| fn run_parallel_helper<'scope>(&self, | ||
| unsafe_flows: &[UnsafeFlow], | ||
| layout_context: &'scope SharedLayoutContext, | ||
| scope: &rayon::Scope<'scope>, | ||
| top_down_func: ChunkedFlowTraversalFunction<'scope>, | ||
| bottom_up_func: FlowTraversalFunction) | ||
| { | ||
| let mut discovered_child_flows = vec![]; | ||
| for unsafe_flow in unsafe_flows { | ||
| let mut had_children = false; | ||
| unsafe { | ||
| // Get a real flow. | ||
| let flow: &mut Flow = mem::transmute(unsafe_flow); | ||
| let flow: &mut Flow = mem::transmute(*unsafe_flow); | ||
|
|
||
| if self.should_record_thread_ids() { | ||
| flow::mut_base(flow).thread_id = proxy.worker_index(); | ||
| // FIXME(emilio): With the switch to rayon we can no longer | ||
| // access a thread id from here easily. Either instrument | ||
| // rayon (the unstable feature) to get a worker thread | ||
| // identifier, or remove all the layout tinting mode. | ||
| // | ||
| // flow::mut_base(flow).thread_id = proxy.worker_index(); | ||
emilio
Author
Member
|
||
| } | ||
|
|
||
| if self.should_process(flow) { | ||
| @@ -170,25 +175,29 @@ trait ParallelPreorderFlowTraversal : PreorderFlowTraversal { | ||
|
|
||
| // If there were no more children, start assigning block-sizes. | ||
| if !had_children { | ||
| bottom_up_func(unsafe_flow, proxy.user_data()) | ||
| bottom_up_func(*unsafe_flow, layout_context) | ||
| } | ||
| } | ||
|
|
||
| for chunk in discovered_child_flows.chunks(CHUNK_SIZE) { | ||
| proxy.push(WorkUnit { | ||
| fun: top_down_func, | ||
| data: (box chunk.iter().cloned().collect(), 0), | ||
| let nodes = chunk.iter().cloned().collect::<Vec<_>>().into_boxed_slice(); | ||
|
|
||
| scope.spawn(move |scope| { | ||
| top_down_func(nodes, layout_context, scope); | ||
| }); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl<'a> ParallelPreorderFlowTraversal for AssignISizes<'a> { | ||
| fn run_parallel(&self, | ||
| unsafe_flows: UnsafeFlowList, | ||
| proxy: &mut WorkerProxy<SharedLayoutContext, UnsafeFlowList>) { | ||
| fn run_parallel<'scope>(&self, | ||
| unsafe_flows: &[UnsafeFlow], | ||
| layout_context: &'scope SharedLayoutContext, | ||
| scope: &rayon::Scope<'scope>) | ||
| { | ||
| self.run_parallel_helper(unsafe_flows, | ||
| proxy, | ||
| layout_context, | ||
| scope, | ||
| assign_inline_sizes, | ||
| assign_block_sizes_and_store_overflow) | ||
| } | ||
| @@ -200,13 +209,13 @@ impl<'a> ParallelPreorderFlowTraversal for AssignISizes<'a> { | ||
|
|
||
| impl<'a> ParallelPostorderFlowTraversal for AssignBSizes<'a> {} | ||
|
|
||
| fn assign_inline_sizes(unsafe_flows: UnsafeFlowList, | ||
| proxy: &mut WorkerProxy<SharedLayoutContext, UnsafeFlowList>) { | ||
| let shared_layout_context = proxy.user_data(); | ||
| fn assign_inline_sizes<'scope>(unsafe_flows: Box<[UnsafeFlow]>, | ||
| shared_layout_context: &'scope SharedLayoutContext, | ||
| scope: &rayon::Scope<'scope>) { | ||
| let assign_inline_sizes_traversal = AssignISizes { | ||
| shared_context: &shared_layout_context.style_context, | ||
| }; | ||
| assign_inline_sizes_traversal.run_parallel(unsafe_flows, proxy) | ||
| assign_inline_sizes_traversal.run_parallel(&unsafe_flows, shared_layout_context, scope) | ||
| } | ||
|
|
||
| fn assign_block_sizes_and_store_overflow( | ||
| @@ -224,20 +233,21 @@ pub fn traverse_flow_tree_preorder( | ||
| profiler_metadata: Option<TimerMetadata>, | ||
| time_profiler_chan: time::ProfilerChan, | ||
| shared_layout_context: &SharedLayoutContext, | ||
| queue: &mut WorkQueue<SharedLayoutContext, WorkQueueData>) { | ||
| queue: &rayon::ThreadPool) { | ||
| if opts::get().bubble_inline_sizes_separately { | ||
| let layout_context = LayoutContext::new(shared_layout_context); | ||
| let bubble_inline_sizes = BubbleISizes { layout_context: &layout_context }; | ||
| root.traverse_postorder(&bubble_inline_sizes); | ||
| } | ||
|
|
||
| run_queue_with_custom_work_data_type(queue, |queue| { | ||
| profile(time::ProfilerCategory::LayoutParallelWarmup, profiler_metadata, | ||
| time_profiler_chan, || { | ||
| queue.push(WorkUnit { | ||
| fun: assign_inline_sizes, | ||
| data: (box vec![borrowed_flow_to_unsafe_flow(root)], 0), | ||
| }) | ||
| let nodes = vec![borrowed_flow_to_unsafe_flow(root)].into_boxed_slice(); | ||
|
|
||
| queue.install(move || { | ||
| rayon::scope(move |scope| { | ||
| profile(time::ProfilerCategory::LayoutParallelWarmup, | ||
| profiler_metadata, time_profiler_chan, move || { | ||
| assign_inline_sizes(nodes, &shared_layout_context, scope); | ||
| }); | ||
| }); | ||
| }, shared_layout_context); | ||
| }); | ||
| } | ||
Some generated files are not rendered by default. Learn more.
Oops, something went wrong.
Oops, something went wrong.
ProTip!
Use n and p to navigate between commits in a pull request.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Do we no longer use this?