#c
#c
Вопрос:
Давайте предположим, что у меня есть tasks
количество задач и threads
количество потоков для их выполнения. Каждый поток может выполняться только один раз, поэтому я хочу равномерно распределить эти задачи по существующим потокам. Чтобы рассчитать количество задач в потоке, я написал это простое приложение:
#include <iostream>
using namespace std;
int main(){
int tasks = 15;
int threads = 8;
if(tasks < threads)
threads = tasks;
int tasksPerThread = tasks / threads;
for (int i = 0, start = 1; i < threads; i ) {
start = tasksPerThread * i 1;
int end = start tasksPerThread - 1;
if (i == threads - 1 amp;amp; end < tasks)
end = tasks;
if(start == end)
cout << "Thread " << i 1 << ": task " << end << endl;
else
cout << "Thread " << i 1 << ": task " << start << "-" << end << endl;
}
return 0;
}
При наличии 16 задач и 8 потоков каждый поток получит по 2 задачи. Но в этом случае при наличии 15 задач с 8 потоками я получаю в результате следующее распределение:
- Поток 1: задача 1
- Поток 2: задача 2
- Поток 3: задача 3
- Поток 4: задача 4
- Поток 5: задача 5
- Поток 6: задача 6
- Поток 7: задача 7
- Поток 8: задача 8-15
Последний поток выполнял бы многие задачи по сравнению с другими, и именно поэтому я хотел бы исправить это распределение, чтобы оно было примерно таким:
- Поток 1: задача 1-2
- Поток 2: задача 3-4
- Поток 3: задача 5-6
- Поток 4: задача 7-8
- Поток 5: задача 9-10
- Поток 6: задача 11-12
- Поток 7: задача 13-14
- Поток 8: задача 15
Мне нужна помощь в исправлении приведенного выше кода, чтобы получить такой результат, при котором каждый поток выполняет одинаковое количество задач. Спасибо.
РЕДАКТИРОВАТЬ: Вот решение благодаря формуле @shananton.
int tasks = 15;
int threads = 8;
if (tasks < threads)
threads = tasks;
int start, usedTasks = 0, tasks_for_this_thread = 0;
for (int i = 0; i < threads; i ) {
usedTasks = tasks_for_this_thread;
start = usedTasks 1;
tasks_for_this_thread = tasks / threads (i < tasks % threads);
int end = start tasks_for_this_thread - 1;
if (start == end)
cout << "Thread " << i 1 << ": task " << end << endl;
else
cout << "Thread " << i 1 << ": task " << start << "-" << end << endl;
}
Комментарии:
1. Разве циклический перебор недостаточно хорош? Во-первых, назначьте каждому потоку задачу. Если остались задачи, назначьте оставшиеся задачи каждому потоку. Простой алгоритм хорош и его легче поддерживать.
Ответ №1:
Чтобы заранее рассчитать количество задач на поток, вы можете использовать эту формулу:
int tasks = 10;
int threads = 3;
for (int i = 0; i < threads; i) {
int tasks_for_this_thread = tasks / threads (i < tasks % threads);
// do whatever you want to
}
Например, для 10 задач и 3 потоков задачи распределяются как 4, 3, 3.
Комментарии:
1. ДА. Эта формула была ключевой. Я опубликовал решение в своем первоначальном сообщении. Спасибо!
Ответ №2:
Простой циклический перебор путем перебора задач.
int tasks(15);
int threads(8);
int thread_index(0);
for( int i = 0 ; i < tasks; i ){
set( thread_index , i ); // pseudo code to start the task
thread_index = ( thread_index 1 ) % threads;
}