【问题标题】:How to optimize this Radix-Sort algorithm in C++?如何在 C++ 中优化这个基数排序算法?
【发布时间】:2022-01-18 09:19:42
【问题描述】:

我正在处理在 C++ 中优化基数排序代码的任务,我需要减少执行时间,我的代码正在运行,它看起来像这样:

void RadixSort::RadixSortNaive(std::vector<long> &Arr) {

long Max_Value = findMax(Arr);

    int Max_Radix = 1;
while (1) {
  if (Max_Radix >= Max_Value) break;
  Max_Radix = Max_Radix*radix_;
}

for (int i = 1; i < Max_Radix; i = i*radix_) {
  for (int j = 0; j < key_length_; j++) {
    int K;
    if (Arr[j] < i) K = 0;
    else K = (Arr[j] / i) % radix_;
    Q[K].push(Arr[j]);
  }

  int idx = 0;
  for (int j = 0; j < radix_; j++) {
    while (Q[j].empty() == 0) {
      Arr[idx] = Q[j].front();
      Q[j].pop();
      idx++;
    }
  }
}
class RadixSort{
public :

  void setConfig(int key_length, int radix) {
    key_length_ = key_length;
    radix_ = radix;
    for (int i = 0; i < radix_; i++) {
      Q.push_back(std::queue<long>());
    }
  }

  long findMax(std::vector<long> Arr) const {
    long Max = 0;
    for (int i = 0; i < key_length_; i++) {
      if (Max < Arr[i])
        Max = Arr[i];
    }
    return Max;
  }

  void RadixSortNaive(std::vector<long> &Arr);
  void RadixSortStudent(std::vector<long> &Arr);

private:
  int key_length_;
  int radix_;
  std::vector<std::queue<long>> Q;
};
}

但是,我确信仍有改进的余地。我一直在尝试使用 OMP 库实现并行化,但似乎没有任何效果。有什么办法可以改进以前的代码吗?也许改进循环或任何其他代码优化技术。

【问题讨论】:

  • findMax 通过值而不是引用获取向量
  • multi-threaded radix sort 的示例代码,但它使用 Windows 本机线程。您可以将其用作基准基准。它对 64 位无符号整数进行排序,并且不考虑最大值,这将有助于减少通过次数,但由于它们是并行的,因此可能没有太大区别。

标签: c++ algorithm optimization radix-sort acceleration


【解决方案1】:

正如 cmets 中所建议的,首先要做的就是正确使用 API。

findMax 可以替换为 std::max_element( ),它使用迭代器,并且不会复制输入。

其他可疑的东西是Q[K].push(Arr[j]);。如果内存允许,至少在每个队列中保留最大数量的元素——否则队列在调整大小时需要复制旧数据。

然后,如果可能,使用没有超出范围检查的原始指针,您可以使用 push()pop()auto popped = *tail++*head++ = new_element; 我的观察是,虽然 STL 正确实现并且可以快速开发,与已知的静态分配相比,在插入中支持动态内存分配实际上总是会降低性能。

第三件事是将基数专门化为 2 的幂,因为现在除法是强度降低到移位,模数是强度降低到逻辑和(通过一些常数,需要计算)。

特别是当基数是 2 的幂时,我想有条件地计算 K==0 是没有用的:if (Arr[j] &lt; i) K = 0;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    • 2013-05-13
    • 2017-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多