Tratando de optimizar el código

Ya casi no tengo mucho tiempo para escribir cosas interesantes :S!

En los siguientes post me gustaria hablar de javascript y Google Maps.

Mi tesis(https://github.com/fedep3/Metaheuriscticas-Data-Clustering) está hecha en C++ y es sobre data clustering  de datos numéricos usando metaheurísticas. Esta enfocada en las imagenes principalmente (las imágenes no son mas que conjuntos de vectores de uno o mas colores).

Actualmente ando investigando y mejorando el código para hacer una poblicacion sobre el algoritmo genético que cree yo con mi companero.

En el código he hecho dos cambios:

  1. Cambiar el generador de numeros aleatorios.
  2. Intentar optimizar la función de la distancia euclideana.

El motivo de l primer cambio era que el generador de numeros aleatorios de C++, es un http://en.wikipedia.org/wiki/Linear_congruential_generator , los cuales son muy eficiente, pero no son tan buenos. Habiendo usado python y ya de hace un tiempo que habia leído del tema decidí colocar el http://en.wikipedia.org/wiki/Mersenne_twister que es de los mejores, por no decir el mejor actualmente. Ahora el reto era buscar que implementecion usar o si hacerla uno mismo. Buscando y probando consegui uno creado por un invetigador de Pixar que hace uso de las instrucciones SSE2 y que es increiblemente eficiente(http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/VERSIONS/C-LANG/cpp_sse2.zip).

Al principio no me compilo asi que busqué lo que estaba pasando. Después de como 1 hora de leer y probar di con la solucion. El código hace uso de unos defines o funciones que por lo visto no estan incluidos en el emmintrin.h. Basto con cambiar el código y listo compilo.  Lo arregle para usarlo y la diferencia de tiempo/resultados con lo que tenia antes ni se notaba.

Averiguando todo este, me surgió un interés por esas instrucciones SSE2. Quería ver si podía programar en ellas la distancia euclideana. Encontre una especia de API de ellas (http://software.intel.com/sites/products/documentation/studio/composer/en-us/2011/compiler_c/index.htm#intref_cls/common/intref_sse2_int_load.htm) y leyendo otras cosas(http://fastcpp.blogspot.comhttps://developer.apple.com/hardwaredrivers/ve/sse.html) entendí su funcionamiento. Las intrucciones son capaces(segun leí y entendí) de procesar 4 flotantes a la vez o 2 doubles.

Mi tesis usa floats, asi que programé lo siguiente:

float Metaheuristic::euclideanDistance(float* v1, float* v2)
{
    __m128 sum = _mm_setzero_ps(), square;
    for(register int k = 0; k < M; k+=4){
        square = _mm_sub_ps( _mm_load_ps(v1 + k), _mm_load_ps(v2 +k));
        sum = _mm_add_ps(_mm_mul_ps(square,square), sum);
    }
    sum = _mm_sqrt_ps(sum);
    _mm_store_ps(eDistance, sum);
    return eDistance[0];
}

Surgieron un montón de problemas para lograr que éesto funcionara. El principal fue que los arreglos que usan estas instrucciones deben tener tamaño divisible entre 4, ya que se cargan los 4 flotantes a los registros. Cambie gran parte del codigo para que a la hora de crear los objetos se cumpliera esta condición y probé de no tener leaks o errors en la memoria usando valgrind. Cuando ya no tuve problemas y los resultados de las corridas tenían coherencia, observé los tiempo. Una imagen que me corria antes en 1 – 2 segundos pasó a 10 segundos !

Mi intento por optimizar el codigo fue fallido, pero aprendi algo. Para mi la razón de que no funcionara muy bien es que los arreglo en realidad eran arreglos de tamano 1 o 3 transformados a 4. Más tiempo se perdía en la carga y cálculo que el que ganaba de tener la capacidad de procesar 4 cosas a la vez. Eso que hasta intente tener las cosas aleanadas a 16 bytes y nada ! Por supuesto que es posible que halla hecho algo mal, pero ahora no tengo mucho tiempo para seguir jugando con el código, ando full de otras cosas.

Espero que ésto sea de ayuda

Advertisements

XSRF Django

En la web uno se debe cuidar de tres cosas (y muchas otras, pero de las principales y más comunes para mí) son: inyecciones SQL, XSS y XSRF.

La primera como dice el nombre es simplemente a través de llamadas HTTP ingresar código de SQL (esto puede aplicar a otro tipo de bases de datos No-SQL). La forma más común es a la hora de un formulario por el cual se pasan datos bien sea por POST o GET, colocar valores estílo ‘; comando sql;  por medio del cual se pueden robar valores, dañar la base datos, etc.

Luego tenemos los XSS, siglas de cross-site scripting, lo cual es ingresar código en la página que se ataca. Ejemplo un párametro que se pasa por GET y que se imprime en la página. Con poner en ese parámetro algo estilo < iframe src = “http://paginamaliciosa” > </ iframe >  se logra que otras personas vean lo que uno desee y se puede robar información u otras cosas.

Finalmente tenemos el XSRF, siglas de cross-site request forergy. Éste ataque es más complejo, pero puede hacer mucho daño. Consiste en hacer que un usuario autentificado en una página haga cosas que él no autorizo. Un ejemplo sería el siguiente:

  • Un usuario anda autentificado en X página, la cual hace el cambio de contraseña por POST.
  • Una persona maliciosa simplemente debe recrear ese request de POST y hacer que el usuario lo haga sin darse cuenta.

Yo ya en un post pasado publique un link (http://google-gruyere.appspot.com/) que encontré muy bueno que habla de seguridad de páginas web y que explican de estos ataques y como defenderse.

Hable de todo ésto ya que me topé con lo siguiente:

https://docs.djangoproject.com/en/dev/ref/contrib/csrf/

Cada día me sorprendo más con lo excelente que es este framework, al igual que Python.

De un modo bastante simple previsto por Django se es posible defenderse de éste último tipo de ataque que comente. No soy un experto de en programación web, nunca me ha gustado, pero me pregunto si muchos de los otros frameworks tienen está capacidad.

Fuera del tema, ya empezó el curso de seguridad ofrecido por la universidad de Standford, espero poder dedicarle, ya vi por encima el material que colocaron y se ve full interesante, espero tener el tiempo y las ganas de leerlo, ya veremos!

Cómo echar código

Un buen rato sin escribir, estar jugando LoL y otras mil cosas no me da mucho tiempo que digamos.

Ando leyendo un libro llamado Clean Code: A Handbook of Agile Software Craftsmanship, el cual se lo recomiendo a toda persona que programe.

En la universidad a uno solo le dicen haz tal cosa y uno mediante google y los conocimientos que se tienen lo hace como puede. Principalmente casi siempre se empieza el código desde cero y donde yo estudie casi siempre es en parejas.

En la vida real las cosas no son así o por lo menos las situaciones que he vivido me han demostrado eso. Usualmente uno va a trabajar con código ajeno que en su vida ha visto. Y acá creo que surge un problema muy común: entender el código ajeno y dar a entender el de uno.

En mi opinión es MUY importante. Siempre se quiere que el trabajo sea de la forma más rápida posible, con la mayor calidad y que sea de forma confortable. Eso depende de entender cosas que tienen puesta los demás y que uno escriba de forma que los otros también les quede claro. Este libre que comente al principio da una serie de tips muy buenos de como hacer esa tarea. Da una serie de ejemplos de código malo y con una serie de cambios logra que sea mucho más fácil de entender. Como todo uno toma lo que desea y lo aprende, es muy posible que algunos tips a uno no le gusten y otros sí. Por donde voy en verdad creo que muchas cosas que habla son en realidad excelente recomendaciones. En muchos casos se sacrifica eficiencia por legibilidad, lo cual en mi opinión siempre depende de lo que uno haga, pero en muchos casos es algo necesario.

Echarle un ojo nunca está demás y creo que en las universidades debería tocarse muchas cosas de esto, en vez de escribir comentarios que siempre se escriben para salirse del paso de ese requerimiento y en muchos casos no quedan claro las cosas.