2016-12-02 4 views
3

В моей программе много циклов, которые можно легко переписать в многопоточность. В основном, для каждой функции, которая должна быть multithreadd я пишу следующую функцию:Многопоточная обертка

void func_to_threaded(int i_from, int i_to, int num_th, ...other_parameters) 
{ 
    int i_min = i_from; 
    int i_max = i_to; 
    int i_inc = i_max/num_th; 
    i_max = i_max % num_th + i_inc; 
    thread* th_dens = new thread[num_th]; 
    for (int i = 0; i < num_th; i++) 
    { 
     th_dens[i] = thread(func_one_thread, i_min, i_max, ...other_parameters); 
     i_min = i_max; 
     i_max += i_inc; 
    } 
    for (int i = 0; i < num_th; i++) th_dens[i].join(); 
    delete[] th_dens; 
} 

Есть ли способ, чтобы переписать, чтобы быть общим для каждой функции вида

void func_one_thread(int i_min, int i_max, ...other_parameters) 
+0

Просто хочу сказать, что функция не выглядит, как она разбивает работу равномерно, если 'i_from' не всегда 0. Пробовал мысленно переживает это с' (3, 8, 2, ...) 'и закончили с' thread (func_one_thread, 3, 4, ...) 'и' thread (func_one_thread, 4, 8, ...) '. Итак, если я не пропустил что-то, это может быть немного неравномерно. –

+0

Да, в моем коде 'i_from' всегда ноль, и теперь я просто попытался переписать его в целом, но не удалось ... – Michal

+0

А. Не слишком хорошо знакомы с многопотоковой обработкой, но, может быть, 'i_inc = (i_max - i_min)/num_th;' будет работать. Вам нужно будет проверить, был ли 'i_max - i_min' чисто делимым на' num_th', хотя, чтобы увидеть, нужно ли какой-либо из потоков выполнять дополнительную работу. –

ответ

0

`ы были некоторое время, так как я задал этот вопрос, и я переехал некоторое время назад от boost threadpool гораздо более элегантный и простой OpenMP как первоначально предложил Mark Setchell. Так что мой код выглядит очень просто

omp_set_num_threads(num_thread); 

#pragma omp parallel for private(private_params) 
for(int i = i_min; i < i_max; i++){ 
    some_func(parameters); 
} 
1

Я не буду отвечать ваш вопрос с шаблоном, хотя это, безусловно, действительный подход. Я собираюсь рекомендовать использовать пул потоков и переносить все ваши действия в общий интерфейс. см .: например 1, 2, с усилением: 3

'stay high level'

+1

Это похоже на комментарий, а не на ответ, даже если я не беру часть буквально «Я не буду отвечать на ваш вопрос». –

1

на основе предложения Piotr Falkowski «s я использовал threadpool с boost библиотеку, чтобы написать этот класс

// header file 
#include "threadpool.hpp" 
class c_Pool 
{ 
public: 
    // CONSTRUCTORS 
    c_Pool(int num_thread); 

    // VARIABLES 
    int num_thread; 
    boost::threadpool::pool th_pool; 

    // METHODS 
    void add_task(int i_from, int i_to, std::function<void(int, int)> func); 
}; 

// main file 
c_Pool::c_Pool(int num_thread): 
    num_thread(num_thread), th_pool(num_thread) 
{} 

void c_Pool::add_task(int i_from, int i_to, function<void(int, int)> func) 
{ 
    int i_min = i_from; 
    int i_max = i_to; 
    int i_inc = (i_max - i_min)/num_thread; 
    i_max = i_from + i_inc // initial i_max 
      + (i_max - i_min) % num_thread; // first thread is doing extra work 

    for (int i = 0; i < num_thread; i++) 
    { 
     auto func_one_thread = bind(func, i_min, i_max);   
     th_pool.schedule(func_one_thread); 
     i_min = i_max; 
     i_max += i_inc; 
    } 
    th_pool.wait(); 
} 

и каждую функцию void some_func(int i_min, int i_max, ...other_parameters) I`m многопоточность с

auto tmp_func = bind(some_func, placeholders::_1, placeholders::_2, ...other_parameters); 
pool.add_task(i_from, i_to, tmp_func); 

EDIT исправлен линия WTH установки начальных i_max

+0

Я не уверен, но не должен 4-я строка 'add_task()' be 'i_max = i_min + ((i_max - i_min)% num_thread + i_inc);'? В настоящее время возможно, что 'i_max' будет таким же или меньше, чем' i_min' после этой строки. (Например, если 'i_from'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' '16',' i_inc' установлен в '4' (' (16 - 8)/2' -> '8/2' ->' 4'), а 'i_max' установлен в' 4' ('(16 - 8)% 2 + 4' -> '8% 2 + 4' ->' 0 + 4' -> '4').) Кроме того, математика выглядит неплохо, насколько я могу судить , –

+0

Да, вы правы. В моей программе я использую 'i_from = 0', поэтому я никогда не сталкивался с этой ошибкой ... – Michal

+0

Если что-то выглядит немного подозрительным, может быть полезно попробовать запустить его с необычными входами, чтобы убедиться, что он работает правильно. –

Смежные вопросы