Connectivity: defer and parallelize item updates
Good for ~15% performance improvement in large designs
This commit is contained in:
parent
6fb1ed2824
commit
654e9a77db
|
@ -1003,9 +1003,6 @@ void CONNECTION_GRAPH::buildConnectionGraph()
|
|||
connection->SetSubgraphCode( subgraph->m_code );
|
||||
}
|
||||
|
||||
for( auto it : invisible_pin_subgraphs )
|
||||
it.second->UpdateItemConnections();
|
||||
|
||||
// Here we do all the local (sheet) processing of each subgraph, including assigning net
|
||||
// codes, merging subgraphs together that use label connections, etc.
|
||||
|
||||
|
@ -1085,8 +1082,6 @@ void CONNECTION_GRAPH::buildConnectionGraph()
|
|||
m_net_name_to_subgraphs_map[new_name].emplace_back( subgraph );
|
||||
|
||||
name = new_name;
|
||||
|
||||
subgraph->UpdateItemConnections();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1161,8 +1156,6 @@ void CONNECTION_GRAPH::buildConnectionGraph()
|
|||
assignNewNetCode( *connection );
|
||||
}
|
||||
|
||||
subgraph->UpdateItemConnections();
|
||||
|
||||
// Reset the flag for the next loop below
|
||||
subgraph->m_dirty = true;
|
||||
|
||||
|
@ -1332,8 +1325,6 @@ void CONNECTION_GRAPH::buildConnectionGraph()
|
|||
else
|
||||
assignNewNetCode( *subgraph->m_driver_connection );
|
||||
|
||||
subgraph->UpdateItemConnections();
|
||||
|
||||
wxLogTrace( ConnTrace, "Re-resolving drivers for %lu (%s)", subgraph->m_code,
|
||||
subgraph->m_driver_connection->Name() );
|
||||
}
|
||||
|
@ -1361,6 +1352,34 @@ void CONNECTION_GRAPH::buildConnectionGraph()
|
|||
for( CONNECTION_SUBGRAPH* subgraph : m_driver_subgraphs )
|
||||
m_sheet_to_subgraphs_map[ subgraph->m_sheet ].emplace_back( subgraph );
|
||||
|
||||
// Update item connections at this point so that neighbor propagation works
|
||||
nextSubgraph.store( 0 );
|
||||
|
||||
auto preliminaryUpdateTask =
|
||||
[&]() -> size_t
|
||||
{
|
||||
for( size_t subgraphId = nextSubgraph++;
|
||||
subgraphId < m_driver_subgraphs.size();
|
||||
subgraphId = nextSubgraph++ )
|
||||
{
|
||||
m_driver_subgraphs[subgraphId]->UpdateItemConnections();
|
||||
}
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
if( parallelThreadCount == 1 )
|
||||
preliminaryUpdateTask();
|
||||
else
|
||||
{
|
||||
for( size_t ii = 0; ii < parallelThreadCount; ++ii )
|
||||
returns[ii] = std::async( std::launch::async, preliminaryUpdateTask );
|
||||
|
||||
// Finalize the threads
|
||||
for( size_t ii = 0; ii < parallelThreadCount; ++ii )
|
||||
returns[ii].wait();
|
||||
}
|
||||
|
||||
// Next time through the subgraphs, we do some post-processing to handle things like
|
||||
// connecting bus members to their neighboring subgraphs, and then propagate connections
|
||||
// through the hierarchy
|
||||
|
@ -1405,7 +1424,6 @@ void CONNECTION_GRAPH::buildConnectionGraph()
|
|||
conn->Name(), subgraph->m_driver_connection->Name() );
|
||||
|
||||
conn->Clone( *subgraph->m_driver_connection );
|
||||
candidate->UpdateItemConnections();
|
||||
|
||||
candidate->m_dirty = false;
|
||||
}
|
||||
|
@ -1477,33 +1495,30 @@ void CONNECTION_GRAPH::buildConnectionGraph()
|
|||
old_sg = old_sg->m_absorbed_by;
|
||||
|
||||
old_sg->m_driver_connection->Clone( *conn );
|
||||
old_sg->UpdateItemConnections();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_net_code_to_subgraphs_map.clear();
|
||||
m_net_name_to_subgraphs_map.clear();
|
||||
nextSubgraph.store( 0 );
|
||||
|
||||
for( CONNECTION_SUBGRAPH* subgraph : m_driver_subgraphs )
|
||||
auto updateItemConnectionsTask =
|
||||
[&]() -> size_t
|
||||
{
|
||||
// Every driven subgraph should have been marked by now
|
||||
if( subgraph->m_dirty )
|
||||
for( size_t subgraphId = nextSubgraph++;
|
||||
subgraphId < m_driver_subgraphs.size();
|
||||
subgraphId = nextSubgraph++ )
|
||||
{
|
||||
// TODO(JE) this should be caught by hierarchical sheet port/pin ERC, check this
|
||||
// Reset to false so no complaints come up later
|
||||
CONNECTION_SUBGRAPH* subgraph = m_driver_subgraphs[subgraphId];
|
||||
|
||||
subgraph->m_dirty = false;
|
||||
}
|
||||
subgraph->UpdateItemConnections();
|
||||
|
||||
if( subgraph->m_driver_connection->IsBus() )
|
||||
{
|
||||
// No other processing to do on buses
|
||||
if( subgraph->m_driver_connection->IsBus() )
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// As a visual aid, we can check sheet pins that are driven by themselves to see
|
||||
// if they should be promoted to buses
|
||||
|
||||
|
@ -1514,10 +1529,11 @@ void CONNECTION_GRAPH::buildConnectionGraph()
|
|||
if( SCH_SHEET* sheet = pin->GetParent() )
|
||||
{
|
||||
wxString pinText = pin->GetText();
|
||||
SCH_SCREEN* screen = sheet->GetScreen();
|
||||
|
||||
for( auto item : sheet->GetScreen()->Items().OfType( SCH_HIER_LABEL_T ) )
|
||||
for( SCH_ITEM* item : screen->Items().OfType( SCH_HIER_LABEL_T ) )
|
||||
{
|
||||
auto label = static_cast<SCH_HIERLABEL*>( item );
|
||||
SCH_HIERLABEL* label = static_cast<SCH_HIERLABEL*>( item );
|
||||
|
||||
if( label->GetText() == pinText )
|
||||
{
|
||||
|
@ -1539,6 +1555,26 @@ void CONNECTION_GRAPH::buildConnectionGraph()
|
|||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
if( parallelThreadCount == 1 )
|
||||
updateItemConnectionsTask();
|
||||
else
|
||||
{
|
||||
for( size_t ii = 0; ii < parallelThreadCount; ++ii )
|
||||
returns[ii] = std::async( std::launch::async, updateItemConnectionsTask );
|
||||
|
||||
// Finalize the threads
|
||||
for( size_t ii = 0; ii < parallelThreadCount; ++ii )
|
||||
returns[ii].wait();
|
||||
}
|
||||
|
||||
m_net_code_to_subgraphs_map.clear();
|
||||
m_net_name_to_subgraphs_map.clear();
|
||||
|
||||
for( CONNECTION_SUBGRAPH* subgraph : m_driver_subgraphs )
|
||||
{
|
||||
auto key = std::make_pair( subgraph->GetNetName(),
|
||||
subgraph->m_driver_connection->NetCode() );
|
||||
m_net_code_to_subgraphs_map[ key ].push_back( subgraph );
|
||||
|
@ -1752,7 +1788,6 @@ void CONNECTION_GRAPH::propagateToNeighbors( CONNECTION_SUBGRAPH* aSubgraph )
|
|||
else
|
||||
{
|
||||
neighbor_conn->Clone( *member );
|
||||
neighbor->UpdateItemConnections();
|
||||
|
||||
recacheSubgraphName( neighbor, neighbor_name );
|
||||
|
||||
|
@ -1853,7 +1888,6 @@ void CONNECTION_GRAPH::propagateToNeighbors( CONNECTION_SUBGRAPH* aSubgraph )
|
|||
wxString old_name = subgraph->m_driver_connection->Name();
|
||||
|
||||
subgraph->m_driver_connection->Clone( *conn );
|
||||
subgraph->UpdateItemConnections();
|
||||
|
||||
if( old_name != conn->Name() )
|
||||
recacheSubgraphName( subgraph, old_name );
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue