From 4efc8dec888c6a2719c102c3309ea905f7a900ee Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Fri, 5 Oct 2018 06:22:20 -0700 Subject: [PATCH] pcbnew: Skip the full itemlist search when updating Updating connectivity should not need to iterate over the full item list in each thread. Instead, we collect the dirty items first and then iterate only over the dirty list. --- pcbnew/connectivity_algo.cpp | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/pcbnew/connectivity_algo.cpp b/pcbnew/connectivity_algo.cpp index 4c722ba8f2..d68c7abae0 100644 --- a/pcbnew/connectivity_algo.cpp +++ b/pcbnew/connectivity_algo.cpp @@ -325,41 +325,38 @@ void CN_CONNECTIVITY_ALGO::searchConnections() PROF_COUNTER search_basic( "search-basic" ); #endif - size_t numDirty = std::count_if( m_itemList.begin(), m_itemList.end(), [] ( CN_ITEM* aItem ) - { return aItem->Dirty(); } ); + std::vector dirtyItems; + std::copy_if( m_itemList.begin(), m_itemList.end(), std::back_inserter( dirtyItems ), + [] ( CN_ITEM* aItem ) { return aItem->Dirty(); } ); if( m_progressReporter ) { - m_progressReporter->SetMaxProgress( numDirty ); + m_progressReporter->SetMaxProgress( dirtyItems.size() ); m_progressReporter->KeepRefreshing(); } if( m_itemList.IsDirty() ) { - std::atomic nextItem( 0 ); + std::atomic nextItem( 0 ); std::atomic threadsFinished( 0 ); size_t parallelThreadCount = std::min( std::max( std::thread::hardware_concurrency(), 2 ), - numDirty ); + dirtyItems.size() ); for( size_t ii = 0; ii < parallelThreadCount; ++ii ) { - std::thread t = std::thread( [&nextItem, &threadsFinished, this]() + std::thread t = std::thread( [&nextItem, &threadsFinished, &dirtyItems, this]() { - for( int i = nextItem.fetch_add( 1 ); - i < m_itemList.Size(); - i = nextItem.fetch_add( 1 ) ) + for( size_t i = nextItem.fetch_add( 1 ); + i < dirtyItems.size(); + i = nextItem.fetch_add( 1 ) ) { - auto item = m_itemList[i]; - if( item->Dirty() ) - { - CN_VISITOR visitor( item, &m_listLock ); - m_itemList.FindNearby( item, visitor ); + CN_VISITOR visitor( dirtyItems[i], &m_listLock ); + m_itemList.FindNearby( dirtyItems[i], visitor ); - if( m_progressReporter ) - m_progressReporter->AdvanceProgress(); - } + if( m_progressReporter ) + m_progressReporter->AdvanceProgress(); } threadsFinished++;