简体   繁体   中英

Parallelizing std::replace on std::deque

First of all I know that multiple writters on a deque are not very easy to handle. But with the following algorithm I can guarantee that there is no concurrent access on elements. The algorithm divides a deque (it is very large, thats the reason why I parallelize it) in chunks and the std::replaces replaces a value in the deque. The problem is, that in some cases after replacing an arbitrary value, the value seems to still exist (btw: it is NOT the case that the new value is the same as the old one). Is it maybe the case that the value is not synced out of the cpu register to the memory? Here the code:

std::deque<int*> _deque;
...
int threadsCount = 25;          
int chunkSize = ceil((float) _deque.size() / (float) threadsCount);                                                                                                                          
std::vector<std::thread> threads;
for (int threadNo = 0; threadNo < threadsCount; threadNo++) {
   std::uint64_t beginIndex = threadNo * chunkSize;
   std::uint64_t endIndex = (threadNo + 1) * chunkSize;
   if (endIndex > _deque.size()) {    
      endIndex = _deque.size();      
   }
   std::deque<int*>::iterator beginIterator = _deque.begin() + beginIndex;
   std::deque<int*>::iterator endIterator = _deque.begin() + endIndex;
   threads.push_back(std::thread([beginIterator, endIterator, elementToReplace, elementNew] () {
      std::replace(beginIterator, endIterator, elementToReplace, elementNew);                                      
   }));
}
for (int threadNo = 0; threadNo < threadsCount; threadNo++) {                                                                                                                               
   threads[threadNo].join();     
}

After that algorithm it is sometimes (not deterministic) the case that a replaced (elementToReplace) value is still in the deque.

Instead of manually implementing such an algorithm, just pass the appropriate execution policy:

std::replace(std::execution::par, deque.begin(), deque.end(), elementToReplace, elementNew);
//           ^^^^^^^^^^^^^^^^^^^
//     executes the algorithm in parallel

Do note that you have to compile with C++17 or later.

它看起来像一个竞争条件,但我无法重现它: http//cpp.sh/5egzm这可能取决于你正在使用的deque实现,但它看起来很奇怪

FYI: Since the above algorithm crashed and the suggested execution policy is still not available on my system I used GNU parallel:

__gnu_parallel::replace(_deque.begin(), _deque.end(), elementToReplace, elementNew);

I will tell you if it worked and the performance stats.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM