Openmp превосходит серийный код с коэффициентом x2, но я хотел бы иметь лучшую производительность, если это возможно.Алгоритм ранцевания, как повысить производительность?
Вот серийный код в C++:
for (int k = 0; k < numelem[i]; k++)
{
sumK = sumK - weight[k];
int cmax = 0;
cmax = max(capacity - sumK, weight[k]);
for (int c = capacity; c >= cmax; c--)
{
if (f[c] < f[c - weight[k]] + value[k])
{
f[c] = f[c - weight[k]] + value[k];
M[capacity * k + c] = 1;
}
}
}
Для версии OpenMP, я использую два f0, f1 массивы, которые поменялись местами на каждой итерации. Это помогает мне предотвратить состояние гонки, но я полагаю, что ложное разделение все еще присутствует (не уверен). Другое мое предположение состоит в том, что условные утверждения внутри прагмы замедляют выполнение.
for (int k = 0; k < numelem[i]; k++) {
sumK = sumK - weight[k];
int cmax = 0;
cmax = max(capacity - sumK, weight[k]);
int c = capacity;
if (k % 2 == 0) {
#pragma omp parallel
{
#pragma omp for
for (c = capacity; c >= cmax; c--) {
//FALSE SHARING???
if (f0[c] < f0[c - weight[k]] + value[k]) {
f1[c] = f0[c - weight[k]] + value[k];
M[capacity * k + c] = 1;
} else {
f1[c] = f0[c];
}
}
}
else {
#pragma omp for
for (c = capacity; c >= cmax; c--) {
//FALSE SHARING???
if (f1[c] < f1[c - weight[k]] + value[k]) {
f0[c] = f1[c - weight[k]] + value[k];
M[capacity * k + c] = 1;
} else {
f0[c] = f1[c];
}
}
}
}
}
Здесь вы можете найти полный код для serial c++ и openmp c++
Эта работа основана на этой статье:
- Solving knapsack problems on GPU by V. Boyera, D. El Baza, M. Elkihel
- работа, связанная с: Accelerating the knapsack problem on GPUs by Bharath Suri
Что такое f []? Что такое M []? Объясните повторение, которое реализует ваш код. –
M - матрица решений, которая содержит решение, принятое на каждой итерации. f - это массив, который используется для вычисления того, должен ли элемент быть частью рюкзака. –
Возможно, вы захотите попробовать [Code Review] (http://codereview.stackexchange.com/), поскольку у вас уже есть рабочий код. – AndyG