Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6999509
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T20:33:02+00:00 2026-05-27T20:33:02+00:00

I would like to iterate through all elements in an std::list in parallel fashion

  • 0

I would like to iterate through all elements in an std::list in parallel fashion using OpenMP. The loop should be able to alter the elements of the list. Is there a simple solution for this? It seems that OpenMP 3.0 supports parallel for loops when the iterator is a Random Access Iterator, but not otherwise. In any case, I would prefer to use OpenMP 2.0 as I don’t have full control over which compilers are available to me.

If my container were a vector, I might use:

#pragma omp parallel for
for (auto it = v.begin(); it != v.end(); ++it) {
    it->process();
}

I understand that I could copy the list into a vector, do the loop, then copy everything back. However, I would like to avoid this complexity and overhead if possible.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T20:33:03+00:00Added an answer on May 27, 2026 at 8:33 pm

    If you decide to use Openmp 3.0, you can use the task feature:

    #pragma omp parallel
    #pragma omp single
    {
      for(auto it = l.begin(); it != l.end(); ++it)
         #pragma omp task firstprivate(it)
           it->process();
      #pragma omp taskwait
    }
    

    This will execute the loop in one thread, but delegate the processing of elements to others.

    Without OpenMP 3.0 the easiest way would be writing all pointers to elements in the list (or iterators in a vector and iterating over that one. This way you wouldn’t have to copy anything back and avoid the overhead of copying the elements themselves, so it shouldn’t have to much overhead:

    std::vector<my_element*> elements; //my_element is whatever is in list
    for(auto it = list.begin(); it != list.end(); ++it)
      elements.push_back(&(*it));
    
    #pragma omp parallel shared(chunks)
    {
      #pragma omp for
      for(size_t i = 0; i < elements.size(); ++i) // or use iterators in newer OpenMP
          elements[i]->process();
    }
    

    If you want to avoid copying even the pointers, you can always create a parallelized for loop by hand. You can either have the threads access interleaved elements of the list (as proposed by KennyTM) or split the range in roughly equal contious parts before iterating and iterating over those. The later seems preferable since the threads avoid accessing listnodes currently processed by other threads (even if only the next pointer), which could lead to false sharing. This would look roughly like this:

    #pragma omp parallel
    {
      int thread_count = omp_get_num_threads();
      int thread_num   = omp_get_thread_num();
      size_t chunk_size= list.size() / thread_count;
      auto begin = list.begin();
      std::advance(begin, thread_num * chunk_size);
      auto end = begin;
      if(thread_num = thread_count - 1) // last thread iterates the remaining sequence
         end = list.end();
      else
         std::advance(end, chunk_size);
      #pragma omp barrier
      for(auto it = begin; it != end; ++it)
        it->process();
    }
    

    The barrier is not strictly needed, however if process mutates the processed element (meaning it is not a const method), there might be some sort of false sharing without it, if threads iterate over a sequence which is already being mutated. This way will iterate 3*n times over the sequence (where n is the number of threads), so scaling might be less then optimal for a high number of threads.

    To reduce the overhead you could put the generation of the ranges outside of the #pragma omp parallel, however you will need to know how many threads will form the parallel section. So you’d probably have to manually set the num_threads, or use omp_get_max_threads() and handle the case that the number of threads created is less then omp_get_max_threads() (which is only an upper bound). The last way could be handled by possibly assigning each thread severa chunks in that case (using #pragma omp for should do that):

    int max_threads = omp_get_max_threads();
    std::vector<std::pair<std::list<...>::iterator, std::list<...>::iterator> > chunks;
    chunks.reserve(max_threads); 
    size_t chunk_size= list.size() / max_threads;
    auto cur_iter = list.begin();
    for(int i = 0; i < max_threads - 1; ++i)
    {
       auto last_iter = cur_iter;
       std::advance(cur_iter, chunk_size);
       chunks.push_back(std::make_pair(last_iter, cur_iter);
    }
    chunks.push_back(cur_iter, list.end();
    
    #pragma omp parallel shared(chunks)
    {
      #pragma omp for
      for(int i = 0; i < max_threads; ++i)
        for(auto it = chunks[i].first; it != chunks[i].second; ++it)
          it->process();
    }
    

    This will take only three iterations over list (two, if you can get the size of the list without iterating). I think that is about the best you can do for non random access iterators without using tasks or iterating over some out of place datastructure (like a vector of pointer).

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I would like to know how to iterate through all the elements in a
Does map() iterate through the list like for would? Is there a value in
Given a new screen in android i would like to iterate through all the
I am using jQuery to iterate through a Javascript object and I would like
I would like to iterate through an array that covers every pixel on my
Here's the situation: I would like to iterate through a table with input controls,
I would like to randomly iterate through a range. Each value will be visited
i would like to iterate over the items of a List<T> , except the
Would like to get a list of advantages and disadvantages of using Stored Procedures.
I have a stl set of integers and I would like to iterate through

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.