背包算法,如何获得更好的性能?

时间:2015-09-01 10:07:20

标签: c++ c algorithm c++11 openmp

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++

的完整代码

这项工作基于这篇文章

2 个答案:

答案 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);

我添加+=之后。