Я пытаюсь понять задачи в intel tbb. Я пытаюсь создать параллельный алгоритм для решения lingfords paring для двух «блоков» L (2, n) (https://en.wikipedia.org/wiki/Langford_pairing)tbb-tasks не принимают заданный параметр
Мой алгоритм работает, когда я вызываю последовательный, но я хочу перевести его в задачи. Это то, что мой алгоритм должен сделать:
- сделать вектор в размере 2 * п, INIT с «0»
- для 0 Недо (1 + счётчика цикла + расстояния из-блоков) < размера вектора делать:
- дублировать заданный вектор
- добавить текущий блок на счётчик цикла
- добавить текущий блок 1 + + расстояние счётчик цикла-из-блоков
- если это не последний блок:
- сделать то же самое в задаче с блочной разницей -1 и дублируют уже заполненный вектор
- еще, проверьте, есть ли «0» левый
- , если нет, то это правильное решение
I в настоящее время игнорировать симметрию
Это текущий код
int langford_task (int step, vector<int> v)
{
task_group g;
int counter = 0;
cout << "current step: "<< step << endl;
cout << "current vector in task: ";
printVector(v);
//'1+var+step' == 1 + our loopcounter + the distance of two 'blocks'
for (unsigned int var = 0; 1+var+step < v.size(); ++var)
{
if (v[ var ] == 0 && v[ 1+var+step ] == 0)
{
vector<int> recV = v;
recV[var] = step;
recV[1+var+step] = step;
cout << "recV = ";
printVector(recV);
if (step - 1 != 0)
{
//make a task with step -1 and the new filled vector
g.run([&]{ counter += langford_task(step-1, recV); }); //spawn a task
}
else
{
// if there is no "0" in our vector, we found a valid solution and return 1
if(!(std::find(recV.begin(), recV.end(), 0) != recV.end()))
return 1;
}
}
}
g.wait(); //wait for tasks
return counter;
}
в теории task_group должна ждать в конце FOOR петли, так что все дети-задача s может закончиться первым.
напечатать вектор, так что я могу видеть то, что находится внутри, и то своего рода странным:
current step: 3
current vector in task: [0, 0, 0, 0, 0, 0, ]
recV = [3, 0, 0, 0, 3, 0, ]
recV = [0, 3, 0, 0, 0, 3, ]
все нормально, пока задача не приходит
current step: 2
current vector in task: [28848976, 0, 0, 0, 0, 3, ]
recV = [28848976, 2, 0, 0, 2, 3, ]
current step: 1
это совершенно странно. Я должен упомянуть, что «28848976» представляется случайным числом. Она всегда разная, большую часть времени его «0»
я ожидал для «текущего вектора в задаче:» в «текущем этапе: 2» -сече-
[3, 0, 0, 0, 3, 0, ]
, потому что это просто параметр я отдал эту функцию.
Он «работает», когда я добавляю g.wait(); // Ожидает задачи
непосредственно под
g.run(...)
но потребляет еще больше времени выполнения, то работать без задач на всех, и, вероятно, не параллельно больше.
current step: 3
current vector in task: [0, 0, 0, 0, 0, 0, ]
recV = [3, 0, 0, 0, 3, 0, ]
current step: 2
current vector in task: [3, 0, 0, 0, 3, 0, ]
recV = [3, 0, 2, 0, 3, 2, ]
current step: 1
current vector in task: [3, 0, 2, 0, 3, 2, ]
recV = [3, 1, 2, 1, 3, 2, ]
Почему эта задача ведет себя так странно? Что я могу сделать, чтобы запустить его?
Просто для завершения, остальная часть кода:
void printVector(vector<int> v)
{
cout << "[";
for (unsigned int var = 0; var < v.size(); ++var) {
cout << v[var] << ", ";
}
cout << "]" << endl;
}
void langford_parallel(int s, int n)
{
cout << "berechne Langenford-Sequenz für S = " << s << " und N = " << n << endl;
// concurrent_vector<int> v((s*n), 0);
vector<int> v((s*n), 0);
int solutions = 0;
solutions = langford_task(n, v);
cout << "found solutions: " << solutions << endl;
}
int main()
{
tick_count t0 = tick_count::now();
// langford_sequentiell(2, 12);
langford_parallel(2, 3);
tick_count t1 = tick_count::now();
cout << "work took " << (t1-t0).seconds() << " seconds." << endl;
return 0;
}
Спасибо за ваш ответ. Я взял счетчик и не использовал tbb :: atomic globalCounter; Это не меняет того факта, что задачи получили [0, 0, 0, 0, 0, 3,] вместо [3, 0, 0, 0, 3, 0,] в качестве аргумента , Я загрузил измененные файлы в http://pastebin.com/xQtuVWpw –
Rhiji
Благодарим вас за улучшение ответа. Я постараюсь скоро это сделать > (голосование приветствуется;) Прошу прощения. Мне нужно «15 репутации», чтобы сделать это, и в настоящее время я получил 3. Я запомню, чтобы вы голосовали за свой ответ, как только я заработал 15 человек. – Rhiji
Это: "" "std :: shared_ptr> recV = new std :: vector (v);" "" просто не компилируется. В Интернете нет ни одного примера хорошего использования, описывающего как std :: shared_ptr <> вокруг вектора. В этом случае компилятор g ++ жалуется на «Преобразование в нескалярный тип» –
Rhiji