Thread the connectivity vector updates

Now that we are dealing with individual connection elements that do not
update their connected elements as well, we can thread the update, just
being careful to guard any remaining updates (bus_enty/busLine) that
need reciprocal updating

Fixes https://gitlab.com/kicad/code/kicad/issues/10974
This commit is contained in:
Seth Hillbrand 2022-03-28 15:34:13 -07:00
parent 776a28a10e
commit 6a53e318e5
1 changed files with 118 additions and 92 deletions

View File

@ -588,10 +588,19 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
// Pre-scan to see if we have a bus at this location // Pre-scan to see if we have a bus at this location
SCH_LINE* busLine = aSheet.LastScreen()->GetBus( it.first ); SCH_LINE* busLine = aSheet.LastScreen()->GetBus( it.first );
for( auto primary_it = connection_vec.begin(); primary_it != connection_vec.end(); primary_it++ ) // We don't want to spin up a new thread for fewer than 4 items (overhead costs)
{ size_t parallelThreadCount = std::min<size_t>( std::thread::hardware_concurrency(),
SCH_ITEM* connected_item = *primary_it; ( connection_vec.size() + 3 ) / 4 );
std::atomic<size_t> nextItem( 0 );
std::mutex update_mutex;
std::vector<std::future<size_t>> returns( parallelThreadCount );
auto update_lambda = [&]() -> size_t
{
for( size_t ii = nextItem++; ii < connection_vec.size(); ii = nextItem++ )
{
SCH_ITEM* connected_item = connection_vec[ii];
// Bus entries are special: they can have connection points in the // Bus entries are special: they can have connection points in the
// middle of a wire segment, because the junction algo doesn't split // middle of a wire segment, because the junction algo doesn't split
// the segment in two where you place a bus entry. This means that // the segment in two where you place a bus entry. This means that
@ -628,6 +637,7 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
else else
bus_entry->m_connected_bus_items[1] = busLine; bus_entry->m_connected_bus_items[1] = busLine;
std::lock_guard<std::mutex> lock( update_mutex );
bus_entry->AddConnectionTo( aSheet, busLine ); bus_entry->AddConnectionTo( aSheet, busLine );
busLine->AddConnectionTo( aSheet, bus_entry ); busLine->AddConnectionTo( aSheet, bus_entry );
} }
@ -697,6 +707,22 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
} }
} }
} }
return 1;
};
if( parallelThreadCount == 1 )
update_lambda();
else
{
for( size_t ii = 0; ii < parallelThreadCount; ++ii )
returns[ii] = std::async( std::launch::async, update_lambda );
// Finalize the threads
for( size_t ii = 0; ii < parallelThreadCount; ++ii )
returns[ii].wait();
}
} }
} }