2014-09-07 3 views
1

У меня есть функция, которая заполняет записи в большой матрице. Поскольку вычисления независимы, я думал об использовании std::thread, так что куски матрицы могут обрабатываться отдельными потоками.Создайте набор потоков итеративно в C++ 11?

Вместо разделения матрицы, чтобы n куски, где n является ограничение на максимальное количество потоков, разрешенных для запуска одновременно, я хотел бы сделать более тонкие куски, так что я мог бы породить новый поток, когда существующий поток законченный. (Поскольку время вычисления будет сильно отличаться для разных записей, и одинаковое разделение матрицы здесь будет не очень эффективным. Следовательно, последняя идея.)

Каковы концепции в std :: thread Я должен изучить это? (Я наткнулся на async и condition_variables, хотя я не ясно вижу, как их можно использовать для таких видов нереста). Некоторый пример псевдо-кода очень поможет!

+6

'Я мог бы порождать новый поток, когда существующий поток завершен.' Почему? Какой смысл позволить одному потоку умереть только, чтобы немедленно создать другой, когда существующий может сделать больше работы так же хорошо? Создайте очередь рабочих элементов, создайте пул рабочих потоков, выберите элементы из этой очереди и обработайте их. –

+0

Это имеет смысл! Благодаря! – mskb

ответ

1

Зачем платить планировщик ОС с созданием потоков & уничтожение? (Предположим, что эти операции дороги.) Вместо этого вместо этого ваши потоки будут работать больше.

EDIT: Если вы не хотите разделить работу на равные куски, лучшим решением является пул потоков. FYI, есть thread_pool library in the works for C++14.

Предполагается, что вы можете разделить работу на равные куски, поэтому это не совсем применимо к вашему вопросу. КОНЕЦ РЕДАКТИРОВАНИЯ.

struct matrix 
{ 
    int nrows, ncols; 
    // assuming row-based processing; adjust for column-based processing 
    void fill_rows(int first, int last); 
}; 

int num_threads = std::thread::hardware_concurrency(); 
std::vector<std::thread> threads(num_threads); 

matrix m; // must be initialized... 
// here - every thread will process as many rows as needed 
int nrows_per_thread = m.nrows/num_threads; 
for(int i = 0; i != num_threads; ++i) 
{ 
    // thread i will process these rows: 
    int first = i * nrows_per_thread; 
    int last = first + nrows_per_thread; 
    // last thread gets remaining rows 
    last += (i == num_threads - 1) ? m.nrows % nrows_per_thread : 0; 
    threads[i] = std::move(std::thread([&m,first,last]{ 
       m.fill_rows(first,last); })) 
} 

for(int i = 0; i != num_threads; ++i) 
{ 
    threads[i].join(); 
} 

Если это операция вы очень часто, а затем использовать бассейн уборщица в @Igor Tandetnik предлагает в комментариях. Для одноразовых, это не стоит проблем.

+1

Разве это не то, чего не хотел OP (разбиение матрицы на куски одинакового размера)? – MikeMB

+0

@MikeMB Ты прав, я неправильно понял вопрос. –

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