es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo optimizar este algoritmo de Radix-Sort en C++?

Estoy trabajando en esta tarea de optimización de un código de radix sort en C++ y necesito reducir el tiempo de ejecución, mi código está funcionando y se ve así:

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;
};
}

Sin embargo, estoy seguro de que aún hay margen de mejora. He estado intentando implementar la paralelización con la biblioteca OMP pero parece que nada funciona. ¿Hay alguna manera en la que pueda mejorar el código anterior? Tal vez mejorando los bucles o cualquier otra técnica de optimización de código.
Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Como experto en TI especializado en C++, algoritmos, optimización, ordenamiento por radix y aceleración, existen varias formas de optimizar el código dado para reducir el tiempo de ejecución. Aquí hay algunas sugerencias:

    1. Paralelización: Como el tamaño del código es lo suficientemente grande, podemos utilizar la paralelización para distribuir la carga de trabajo entre varios hilos o núcleos, acelerando así el proceso de ordenamiento. Para hacer esto, podemos utilizar OpenMP o cualquier otra biblioteca de programación paralela. Sin embargo, el enfoque de paralelización debe ser planificado cuidadosamente para optimizarlo aún más.
    2. Actualización de la función findMax: Podemos optimizar la función findMax utilizando la función std::max_element, que devuelve el elemento máximo en el rango de elementos proporcionados. Esto se puede hacer de la siguiente manera:

    long findMax(std::vector<long> Arr) const {
        return *(std::max_element(Arr.begin(), Arr.end()));
    }
    
    1. Uso de punteros: Como acceder a los elementos de un arreglo puede llevar tiempo, podemos utilizar punteros en su lugar para acelerar el proceso.

    2. Uso de vectores en lugar de colas: Los vectores son más rápidos que las colas. Por lo tanto, podemos utilizar un vector en lugar de una cola. Los vectores son contiguos y, por lo tanto, podemos acceder a sus elementos utilizando punteros, lo que los hace más rápidos.

    3. Reducción de la sobrecarga de bucle: La sobrecarga de bucle es un costo computacional adicional que se agrega debido a la ejecución repetida de un bucle. Podemos reducir esta sobrecarga optimizando los bucles de la siguiente manera:

    for (int i = 1, radix_ = radix_ * radix_; i < Max_Radix; i *= radix_) {
        for (int j = 0; j < key_length_; j++) {
            int K = (Arr[j] / i) % radix_;
            Q[K].push(Arr[j]);
        }
        int idx = 0;
        for (auto &q : Q) {
            while (!q.empty()) {
                Arr[idx++] = q.front();
                q.pop();
            }
        }
    }
    

    Al realizar las actualizaciones mencionadas anteriormente, podemos optimizar aún más el código y reducir el tiempo de ejecución.

Comments are closed.