От расстановки скобок произведение не зависит, а от порядка множителей зависит.
Вот лично я перемножаю vector<Qt>, Qt - мой собственный класс для кватернионов, оператор умножения для них есть, разумеется.
Всякие методы типа std::reduce принимают initial value, что намекает, что хрен его знает, как он множители при разных ExecutionPolicy переставит.
C/C++
Как стандартно распараллелить ассоциативное умножение в C++? Перемножаем, например, 1000 элементов.
#include <vector>
#include <numeric>
#include <iostream>
using namespace std;
long long product(const vector<long long>& box) {
if (box.empty()) return 0;
if (box.size() == 1) return box[0];
int n = static_cast<int>(box.size());
auto len = n >> 1;
if (n & 1) ++len;
vector<long long> acc(len);
for (auto i = 1, j = 0; i < n; i += 2, ++j) {
acc[j] = box[i] * box[i - 1];
}
if (n & 1) acc.back() = box.back();
if (len == 2) return acc[0] * acc[1];
else return product(acc);
}
int main() {
vector<long long> box(15);
iota(box.begin(), box.end(), 1);
for (auto x : box) cout << x << ' ';
puts("");
auto p = product(box);
cout << p << '\n';
}
P.S. Так что ли?
#include <numeric>
#include <iostream>
using namespace std;
long long product(const vector<long long>& box) {
if (box.empty()) return 0;
if (box.size() == 1) return box[0];
int n = static_cast<int>(box.size());
auto len = n >> 1;
if (n & 1) ++len;
vector<long long> acc(len);
for (auto i = 1, j = 0; i < n; i += 2, ++j) {
acc[j] = box[i] * box[i - 1];
}
if (n & 1) acc.back() = box.back();
if (len == 2) return acc[0] * acc[1];
else return product(acc);
}
int main() {
vector<long long> box(15);
iota(box.begin(), box.end(), 1);
for (auto x : box) cout << x << ' ';
puts("");
auto p = product(box);
cout << p << '\n';
}
P.S. Так что ли?
не очень понимаю, в чем именно проблема. я задачу понял не так, как Николай.
Вариант 1:
Создай 10 тредов, в каждом перемножь пачку из 100 кватернионов.
Дождись окончания тредов, перемножь их результаты.
Кол-во тредов лучше сделать параметром, т. к. на разном железе оптимальное кол-во тредов будет разным. Слишком много - плохо еще и потому, что тебе надо хранить промежуточные результаты, а это - память.
Вариант 2: больше подходит для случая, когда выполнение одного из тредов намного дольше, чем остальных. Тогда лучше пойти через ТредПул и очередь задач.
Добавляешь в очередь задачи на перемножение.
Тред Пул:
1) При добавлении задачи, если у него есть "свободный" тред - запускает задачу в нем, иначе - оставляет в очереди
2) При завершении треда - проверяет, что в очереди есть задачи. Если есть - отдает первую освободившемуся треду.
Соответственно, если один из тердов долго пыхтит - остальные в это время все остальные задачи выполнят.
У меня по этому варианту МТ-загрузка объектов из файла организована.
Вариант 1:
Создай 10 тредов, в каждом перемножь пачку из 100 кватернионов.
Дождись окончания тредов, перемножь их результаты.
Кол-во тредов лучше сделать параметром, т. к. на разном железе оптимальное кол-во тредов будет разным. Слишком много - плохо еще и потому, что тебе надо хранить промежуточные результаты, а это - память.
Вариант 2: больше подходит для случая, когда выполнение одного из тредов намного дольше, чем остальных. Тогда лучше пойти через ТредПул и очередь задач.
Добавляешь в очередь задачи на перемножение.
Тред Пул:
1) При добавлении задачи, если у него есть "свободный" тред - запускает задачу в нем, иначе - оставляет в очереди
2) При завершении треда - проверяет, что в очереди есть задачи. Если есть - отдает первую освободившемуся треду.
Соответственно, если один из тердов долго пыхтит - остальные в это время все остальные задачи выполнят.
У меня по этому варианту МТ-загрузка объектов из файла организована.
Сергей Зайцев
Хочется стандартный one-liner из STL или, на худой конец, из boost.
Задача-то стандартная;.
Задача-то стандартная;.
Наталия Спирина
Тот еж кватернион есть и в boost, но у тебя-то свой. Так почему бы и работу с потоками самостоятельно не сделать?
Ста ита такое сир?
Сергей Зайцев
Сир, алгебра.
В математике фигова туча операций умножения, для которых сочетательное свойтсво умножения выполняется, а пермеестительное не выполняется.
Я хочу заставить его выполнять операцию типа
a*b*c*d*e*f
параллельно.
Но только так, чтоб он множители не переставлял. А скобки пусть сам расставляет, как ему удобно.
Например, a*b*c посчитает пусть в одном потоке, d*e*f - в другом, если уме так нравится. А потом переножит полученные значения (abc)(def)
В математике фигова туча операций умножения, для которых сочетательное свойтсво умножения выполняется, а пермеестительное не выполняется.
Я хочу заставить его выполнять операцию типа
a*b*c*d*e*f
параллельно.
Но только так, чтоб он множители не переставлял. А скобки пусть сам расставляет, как ему удобно.
Например, a*b*c посчитает пусть в одном потоке, d*e*f - в другом, если уме так нравится. А потом переножит полученные значения (abc)(def)
Похожие вопросы
- Написать программу на C/C++. Найти количество отрицательных элементов под побочной диагональю.
- Код на c++ выводит неправильную сумму элементов побочной диагонали двумерного массива
- Дан массив из N элементов (N < 1000), причем N - четное. Вставить в середину массива сумму всех элементов.
- Заполнить двумерный массив 5*3 и найти строку с максимальным произведением элементов. C++
- Создание программы на вычисление большего количества положительных или отрицательных элементов в среде c++
- C++ как найти N-ый максимальный элемент масива?
- Элементы Матрицы C++
- Как удалить элемент массива в C++
- Заменить нулями элементы массива, которые расположены между первым минимальным и последним максимальным элементами масси
- Не могу разобраться. Функция удаления отрицательных элементов вектора
1 - 2
1 - 3
1 - 4
1 - 6
2 - 1
2 - 3
2 - 4
2 - 5
3 - 1
3 - 2
3 - 5
3 - 6
4 - 1
4 - 2
4 - 5
4 - 6
5 - 2
5 - 3
5 - 4
5 - 6
6 - 1
6 - 3
6 - 4
6 - 5