дождитесь результатов в l oop при заказе - PullRequest
0 голосов
/ 05 апреля 2020

Попытка упорядочить вычислительный метод, затем дождаться сбора результатов всех вычислений и сохранить их в std :: list с другим вводом данных, поэтому не вижу улучшений производительности. Может быть, если я знаю 'num_results', я смогу каким-то образом объединить оба цикла и сохранить данные в списке только с помощью процедуры блокировки (мьютекса) записи (push_back)? Другое дело, как сохранить порядок (если на некоторых [i] вычисления выполняются быстро) Выполнение этого за один цикл в одном ядре слишком медленное.

// here is pseudocode 

void SomeClass::SomeMethod() {
  size_t num_results = request_list.size();
  std::list<result_t> some_results;
  float *result = new float[num_results];
  // linearly I do one for in where one parameter of list pushing are long computing function
  // so I create array of function results and try to store data same time then wait and collect in list with other data
  for (size_t i(0); i < num_results; i++) {
     // Calculate is hard function and may vary in times depending on imput
     // use temporary thread object and labda function to acces class members data
     thread t([&]() { result[i] = Calculate(request_list[i]); });
     // where or how to wait for all results stored in array only then push them to list?

     t.join(); // where or how to wait for all result[] for next cycle or merge both? 
  } 
  // conjugate result with some other data from static list with same id's
  for (std::size_t i(0); i < num_requests; i++) {
      some_results.push_back( result_t(result[i], other_data[i], ...) );
  }

  delete [] result; // free memory

   // Continue job with some_results list

}

Неправильно ли выполняется паррализм?

Ответы [ 2 ]

0 голосов
/ 07 апреля 2020
// solution for dynamic async threads with store results 
// after lots of documentation reading of multithreading
// function do asynchronic calls of N count of heavy ops then waits in idle 
// cycle to aquire all results, if first is ready push it to vector
// while it waits for first result accesible, next maybe ready allready    


void SomeClass::SomeMethod() {
   auto request_util = [&](std::size_t i) { return Calculate(i); };
   size_t num_results = request_list.size();
   std::list<std::future<float>> request_respond_list;
   for (std::size_t i(0); i < num_requests; i++)
      request_respond_list.push_back( std::async(std::launch::async, request_util, i));

   std::size_t id(0);

   // example of result storing
   // float *result = new float[num_results];
   std::vector< result_t > results;
   while (!request_respond_list.empty()) {
      if (request_respond_list.front().valid()) {
          results.push_back(result_t(request_respond_list.front().get(), other_data[id]));
          request_respond_list.pop_front();
          id++;
      } else
         std::this_thread::yield();
   } request_respond_list.clear();

  // do other job with results vector
   ....
}
0 голосов
/ 05 апреля 2020

Посмотрите снова на функцию join, вы запускаете поток для вычисления, ждете этот поток и запускаете другой поток после этого. Вместо этого вы должны запустить несколько потоков и присоединиться к ним впоследствии. Ваш порядок операций неправильный, потому что вы ожидаете каждого потока.

http://www.cplusplus.com/reference/thread/thread/join/

...