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数组,在每次迭代时交换。这有助于我防止竞争条件,但我认为错误共享仍然存在(不确定)。其他我的假设是,pragma中的条件语句可以减慢执行速度。
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++
的完整代码这项工作基于这篇文章 :
答案 0 :(得分:0)
免责声明:我不知道算法是什么或应该做什么。
我会保持代码简单,并通过使用局部变量(如果可能)完全避免错误共享。
import rethinkdb as r
答案 1 :(得分:0)
我不知道编译指令的用途是什么,但是关于算法,你可以优化这部分:
for (c = capacity; c >= cmax; c--) {
我猜测capacity
表示背包的整个容量。
这个想法是你并不总是需要从此开始迭代。从您当前访问过的项目的权重总和开始迭代就足够了。
所以你可以这样做:
currentCapacity = 0;
for (int k = 0; k < numelem[i]; k++) {
currentCapacity += weight[k];
sumK = sumK - weight[k];
int cmax = 0;
cmax = max(currentCapacity - sumK, weight[k]);
int c = currentCapacity;
if (k % 2 == 0) {
#pragma omp parallel
{
#pragma omp for
for (c = currentCapacity; c >= cmax; c--) {
它不会影响大的复杂性,但它应该在实践中提供性能提升,特别是如果你有大容量。
在此之后,你还应该强制当前的容量永远不会超过背包的容量:
currentCapacity = min(currentCapacity, capacity);
我添加+=
之后。