Problemas con bucles for

Iniciado por javier_macross, 12 Octubre 2012, 03:54 AM

0 Miembros y 3 Visitantes están viendo este tema.

javier_macross

Hola amigos de esta estupenda web. Ojalá y me puedan ayudar con un problema. Tengo el siguiente código:

void _vect_mat(float *vect,float **mat){
  float temp[4];

  temp[0] = vect[0];
  temp[1] = vect[1];
  temp[2] = vect[2];
  temp[3] = vect[3];

  vect[0] = (temp[0] * mat[0][0]) + (temp[1] * mat[1][0]) + (temp[2] * mat[2][0]) + (temp[3] * mat[3][0]);
  vect[1] = (temp[0] * mat[0][1]) + (temp[1] * mat[1][1]) + (temp[2] * mat[2][1]) + (temp[3] * mat[3][1]);
  vect[2] = (temp[0] * mat[0][2]) + (temp[1] * mat[1][2]) + (temp[2] * mat[2][2]) + (temp[3] * mat[3][2]);
  vect[3] = (temp[0] * mat[0][3]) + (temp[1] * mat[1][3]) + (temp[2] * mat[2][3]) + (temp[3] * mat[3][3]);
}

int main(){
  int i,j,k;

  float *vect,**mat;

  vect =  (float *)malloc(4 * sizeof(float));
  mat  = (float **)malloc(4 * sizeof(float *);
  for(i=0;i<4;i++)mat[i] = (float *)malloc(4 * sizeof(float));

  vect[0] = 1.0;
  vect[n] = ......etc.

  mat[0][0] = 1.0;
  mat[n][m] ......etc.     

  while (1){
    for(i = 0;i < 5;i++){
      for(j = 0;j< 6;j++){
        for(k = 0;k < 3600;k++)_vect_mat(vect,mat);  <---Problema
      }
    }
  }
}


Esto es sólo parte de un programa hecho con OpenGL.

El problema es que cuando llamo a la función "_vect_mat" los frames por segundo se caen a sólo 12. Pero si la quito, regresa a 75 (mi refresco de monitor).

¿Podría alguien ayudarme?

Muchas Gracias.
;-)

do-while

¡Buenas!

Hay alguna cosilla...

  mat  = (float **)malloc(4 * sizeof(float *)); /* faltaba el parentesis final */


El problema supongo que estara en que dentro del bucle estas haciendo 3600 llamadas a la funcion y esta trabaja con numeros de coma flotante. Trabajar con floats o doubles es "mucho" mas costoso que trabajar con enteros y supongo que por eso te ira mas lento.

Danos mas informacion sobre los valores del vector y de la matriz, ya que si estan acotados (dentro de un minimo y un maximo) igual se pueden utilizar valores enteros para describir el problema y a la hora de tener que utilizar los valores del vector en otra parte se podrian traducir a floats...

¡Saludos!
- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!

javier_macross

Muchas gracias por responder. Ahora que lo dices, tienes razón. Lo más probable es que el hecho de manejar multiplicaciones entre float, haga que el proceso entero se alente.

Voy a probar con *half float. Si funciona te cuento.

De nuevo muchas gracias y saludos.
;-)

*half float es una variable que maneja sólo la mitad de precición que el float. Este no pertenece al C/C++ estándar, así que se debe implementar ya sea usando código o con la ayuda de librerías.

javier_macross

#3
Pues bien, ya lo revisé. No funciona bien, porque si por un lado half float es más pequeño, los CPU's nativamente no lo soportan. Por lo que supone implementar esto de otro modo.

La única opción es empleando shaders, esto se hace en la programación gráfica. Los GPU`s sí soportan los half float por lo que los cálculos pasan a la GPU y liberan de mucho a la CPU.

Sin embargo tenías razón, el uso de float en las operaciones y más cuando son muchísimas, implica un uso del CPU muy grande, por lo que se deben sustituir o en el caso de tener que usarlas en la programación gráfica, es decir en tiempo real, de preferencia al principio fuera del bucle principal.

Muchas gracias por tu ayuda.

Saludos.
;-)

P. D. Perdón por el doble post. :¬¬

do-while

¡Buenas!

No se que precision te hace falta, ni que tamaño de datos estas utilizando.

Siempre puedes recurrir a utilizar por ejemplo una cantidad fija de decimales. Asi cada elemento de la matriz lo puedes multiplicar por ejemplo por 10 y quedarte con la parte entera (transformas los elementos de la matriz en ints (bij) = 10 * aij. Cada elemento del vector lo multiplicas tambien por 10 vi = 10 * vi, realizas la operaciones con los valores enteros y al terminar tendras que dividir por cien cada elemento del vecto para recuperar los datos de tipo float. La matriz la puedes guardar con valores enteros (suponiendo que sus valores sean constantes), y asi solo tendras que realizar 2n operaciones de float, con n la dimension del espacio que manejes, en lugar del monton de operaciones que realizabas antes...

Siempre puedes utilizar mas decimales, pero ten en cuenta que si multiplicas el vector y la matriz por 100, estaras tratando con valores que son 10000 veces superiores a lo que deberian ser, por lo tanto corres el peligro de salirte del rango de los enteros segun lo grandes que sean los valores que manejas...

¡Saludos!
- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!

javier_macross

Sí, eso ya lo había pensado. Pero no lo implementé debido efectivamente al problema del overflow.

Está bien la precisión de 6 dígitos de matisa. Ahora lo que hice fue pasar la mayoría de datos (que de momento no los había visto) que permanecían constantes, al principio del programa y que quedarán fuera del bucle principal.

Con eso he logrado recuperar la mayor parte del rendimiento.

Muchas gracias amigo, por tu estupenda ayuda.

Saludos.
;-)