[PATCH] D148916: [Support][Parallel] Initialize threadIndex and add assertion checking its usage.

Alexey Lapshin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 25 14:16:45 PDT 2023


avl added a comment.

Btw, looking at circt/llvm/mlir/include/mlir/IR/Threading.h it seems that it does not use llvm::parallel::parrallelFor and already uses similar solution with separate ThreadPool. Thus it looks like we can remove "NumItems > 1" workaround in llvm/lib/Support/Parallel.cpp

  template <typename IteratorT, typename FuncT>
  LogicalResult failableParallelForEach(MLIRContext *context, IteratorT begin,
                                        IteratorT end, FuncT &&func) {
    unsigned numElements = static_cast<unsigned>(std::distance(begin, end));
    if (numElements == 0)
      return success();
  
    // If multithreading is disabled or there is a small number of elements,
    // process the elements directly on this thread.
    if (!context->isMultithreadingEnabled() || numElements <= 1) {
      for (; begin != end; ++begin)
        if (failed(func(*begin)))
          return failure();
      return success();
    }
  
    // Build a wrapper processing function that properly initializes a parallel
    // diagnostic handler.
    ParallelDiagnosticHandler handler(context);
    std::atomic<unsigned> curIndex(0);
    std::atomic<bool> processingFailed(false);
    auto processFn = [&] {
      while (!processingFailed) {
        unsigned index = curIndex++;
        if (index >= numElements)
          break;
        handler.setOrderIDForThread(index);
        if (failed(func(*std::next(begin, index))))
          processingFailed = true;
        handler.eraseOrderIDForThread();
      }
    };
  
    // Otherwise, process the elements in parallel.
    llvm::ThreadPool &threadPool = context->getThreadPool();
    llvm::ThreadPoolTaskGroup tasksGroup(threadPool);
    size_t numActions = std::min(numElements, threadPool.getThreadCount());
    for (unsigned i = 0; i < numActions; ++i)
      tasksGroup.async(processFn);
    // If the current thread is a worker thread from the pool, then waiting for
    // the task group allows the current thread to also participate in processing
    // tasks from the group, which avoid any deadlock/starvation.
    tasksGroup.wait();
    return failure(processingFailed);
  }


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148916/new/

https://reviews.llvm.org/D148916



More information about the llvm-commits mailing list