diego sevilla’s weblog
it is better to remain silent and be thought a fool,
than to open your mouth and remove all doubt -- groucho marx

19/11/2010

Hispania F1 Racing Team

Esta semana (el martes, creo recordar) hubo una charla de este grupo de fórmula uno con capital español (murciano, para más señas). Quizá es que esperaba más de esto, mucha tecnología al límite, ingeniería de desarrollo, pruebas, ciclos cortos de desarrollo, etc., pero me desilusionó un poco la charla.

Explicaré por qué. No pude ir al principio de la charla porque estaba dando clase en el máster de la asignatura «Software como servicio y distribuido» hasta las 5 de la tarde, y la conferencia había empezado a las 4. Con todo, cuando llegué estaban en turno de preguntas, y pude hacerme una idea de lo que había sido la presentación, aunque me habría gustado verla desde el principio.

Parece que no fue excesivamente técnica, al menos en la parte que nos interesa a los informáticos, porque una de las preguntas que se hicieron tuvo que ver con el lenguaje de programación o entorno que utilizaban. La respuesta del ingeniero informático:

- Utilizamos C#. Cuando entré a trabajar en la empresa venía de experiencia de programación en C++. Cuando me explicaron lo que tenía que hacer me eché las manos a la cabeza. Eso no se podía hacer con C++. Aprendí en un par de semanas C# e hicimos el programa.

Como se puede suponer, tengo miles de comentarios a este respecto. Primero, sí que pude ver el interfaz gráfico que habían hecho. Interfaces con esa complejidad estamos acostumbrados a hacer en C++ y Qt para SAES en la Cátedra de Software libre, y no nos echamos las manos a la cabeza. El hecho de que un ingeniero en particular no tenga el conocimiento suficiente, o tenga que tomar una decisión acelerada no sé si debería decidir una estrategia para el futuro. Además, aprender en un par de semanas C# no parece lo más adecuado para hacer un programa de calidad, pero en fin. Continuaba:

- La salida de este programa son ficheros XML que utilizamos para comunicar con los equipos de carrera

Esto es mi favorito. Al nombrar XML parece que todo el mundo dice «ah, claro». XML ya hace que los programas interactúen mágicamente… En fin. ¿Por qué no JSON/YAML? Reconozco que esto es más una manía mía, pero ¿por qué en los nuevos desarrollos de bases de datos (CouchDB, MongoDB) no se utiliza XML sino formatos más sencillos y expresivos?

Me hubiera gustado preguntarles por sus ciclos de desarrollo, pruebas, etc., pero como había llegado tarde, ahí se quedó.

La conversación, a raíz de otra pregunta, giró hacia la colaboración de estos grupos con la Universidad. Uno de los ponentes (no recuerdo su nombre) había estado trabajando para Red Bull anteriormente, y contaba proyectos de colaboración que sus antiguos patronos tenían con Universidades. No es el caso de Hispania, según decía, por problemas políticos, o por problemas de medios de las universidades (laboratorios con material especializado, etc.)

En este punto hice una pregunta, dado que tenemos experiencia en colaborar con una empresa, pregunté que para tener una colaboración a nivel de informática no se necesitaban laboratorios especializados (sólo ordenadores y personas). Uno de los ingenieros del equipo (presumo) me interrumpió gritando que «¿Cómo que no necesitas? Para empezar necesitas un superordenador». Intenté responderle a medio hacer la pregunta que no se necesita un supercomputador in situ sino una persona que sepa cómo hacer los programas paralelos que aprovechen en superordenador, y una conexión internet para conectarse al CESGA o al Mare Nostrum (en los tiempos de Internet, los ordenadores no tienen que estar en tu habitación, aparte de que tenemos Ben Arabí, creo recordar de la última vez que estuve allí… Además, ¡¡programan en C#!!, ¿qué supercomputador???)… Cuando me dejó terminar la pregunta, la respuesta del ponente era la misma, cuestiones políticas que escapaban a su nivel de puesto de trabajo que hacía que no se colaborara con la Universidad tampoco en informática. Creo que nuestra experiencia en testing, modelado, etc., sería interesante para ellos, pero aquí estamos.

Finalmente, fallo garrafal (según mi punto de vista). Se quejaban de que tenían un presupuesto limitado, y utilizan software propietario, licencias, etc., en vez de sacar partido al software libre (incluso para C# existe Mono…).

Espero que los ingenieros en otras ramas estén más al día, porque si no, el equipo va a ganar pocas carreras :)

9/2/2010

Primera aproximación de un mecanismo de actores para C++

Filed under: General, español, código/code, free software/software libre — Diego Sevilla @ 13:34 — In English

Desde hace tiempo quiero escribir esta entrada, pero por falta de tiempo no he podido. El mecanismo de actores se utiliza en lenguajes de programación como Erlang y Scala para sincronizar diferentes «actores» que están funcionando en el sistema. Tradicionalmente, la programación con hilos (salvo en casos como BSP, por ejemplo) se ha realizado básicamente como la programación monoproceso, pero haciendo que el programador tuviera en la cabeza las posibles colisiones que varios hilos ejecutando un código podrían tener.

La otra cara de esta moneda la han tenido lenguajes y paradigmas que cambiaban la manera de programación hacia esquemas que hicieran más fácil escalar en el número de hilos/cores a la vez que permitían una programación más natural de programas multihilo. Estos nuevos paradigmas también evitaban, por diseño, los problemas que se dan con los candados, reentrancia, etc.

El paradigma sobre el que hablaré hoy es el de los actores. Este mecanismo, que data de 1986, se utiliza en Erlang y en Scala, por ejemplo, pero no he encontrado ejemplos de cómo implementar este mecanismo en C++, salvo un artículo de 1993 de Kafura, Mukherji y Lavender en el que no se hace uso de ninguna característica «moderna» de C++, como los tipos parametrizados o la sobrecarga de operadores.

En resumen, el mecanismo de actores se basa en definir un actor como un objeto reactivo que se ejecuta en su propio hilo. Son similares a los objetos stricto sensu, en el sentido de que se les puede enviar invocaciones (en mi caso eventos), y los actores responden ejecutándolos, como los objetos normales. No obstante, son diferentes porque las invocaciones se ejecutan de manera que no causan problemas de concurrencia. ¿Cómo? Pues asegurando que todas las invocaciones sobre un actor se ejecutan en un mismo hilo. En este sentido, un actor también aglutina, en general, un hilo de ejecución propio en el que se ejecutan las llamadas al mismo (esto puede no ser así exactamente, pero la idea es la misma).

Existe una diferencia con los paradigmas tradicionales de programación. Por ejemplo, para no causar problemas de concurrencia, todos los métodos de un objeto se podrían marcar como «synchronized» al estilo de Java. Esto, efectivamente, hace que no haya problemas de concurrencia (al menos los más usuales), ya que todas las invocaciones a un objeto se realizan en exclusión mutua. Sin embargo, una invocación a objeto normal lleva consigo asociada un hilo de ejecución, y el hilo de ejecución del objeto llamante es el que realiza la llamada al objeto llamado, con lo que también se tienen que prevenir problemas como interbloqueos, esperas de candados, etc.

En resumen, sería casi como un sistema basado en eventos en donde los objetos se envían mensajes que son a su vez procesados en los hilos respectivos de cada actor. Ahora bien, ¿cómo implementar en C++ este mecanismo sin ser excesivamente intrusivo, teniendo en cuenta que el mecanismo de envío de eventos no existe en C++? Pensé en utilizar boost.signal, pero éste no asegura que el objeto receptor va a ejecutar la señal en su propio hilo. Los requisitos que establecí pues para el desarrollo fueron los siguientes:

  1. El mecanismo debe ser poco intrusivo, en el sentido de que las clases que quieran beneficiarse de este mecanismo no tienen por qué escribirse heredando de un interfaz en particular, sino que sólo tienen que definir una serie de tipos para saber tratarlas como actor.
  2. Cualquier clase puede definir de manera sencilla qué eventos puede recibir y cómo actuará ante cualquier evento, y estos serán los únicos requisitos que tendrá que especificar la clase.
  3. Las clases pueden modificar de forma sencilla qué eventos producen y reciben.
  4. Las clases no tendrán que preocuparse de tratar con hilos, asincronía, almacenamiento y reproducción de eventos, etc.
  5. El mecanismo de envío de eventos debe estar integrado en el lenguaje C++ de forma natural. Por ejemplo, con un operador que muestre que se está enviando un evento: objeto < < mensaje;.

Con estos requisitos, pensé hacer la clase actor que pudiera aceptar como parámetro cualquier otra clase, y convertirla así en un actor. Este mecanismo es poco intrusivo, sólo obligando a que la clase que se quiere beneficiar de este mecanismo especifique qué eventos es capaz de recibir. La clase actor que me quedó fue la siguiente, con comentarios al estilo de la literate programming (si alguien está interesado le puedo pasar el código sin los comentarios):

template <typename Klass>
struct actor
{
    typedef typename Klass::events_type VariantType;

Uno de los requisitos que tiene que proveer la clase que se va a convertir en actor es ofrecer el tipo VariantType con los distintos eventos que va a poder recibir. Para esto se usará el tipo boost.variant como se verá después.

    typedef actor<Klass> self;

    actor (Klass& a)
        : delegate_ (a)
    {
        thread_ = boost::thread (boost::ref (*this));
    }

Cada actor posee su propio hilo. Esto, por supuesto puede modificarse después. Sólo quería hacer una prueba de concepto. En scala existen schedulers que enlazan actores con hilos.

    // Thread func.
    void operator()()
    {
        std::cout << “running thread” << std::endl;

        while(!stop_)
        {
            bool b;
            {
                boost::lock_guard<boost::mutex> guard (list_mutex_);
                b = el_.empty();
            }

            if (b)
            {
                boost::unique_lock<boost::mutex> lock (mut_);

                // wait on the cond. var.
                cond_.wait (lock);
            }

            while (true)
            {
                VariantType vtv;
                {
                    boost::lock_guard<boost::mutex> guard (list_mutex_);
                    if (el_.empty())
                        break;

                    vtv = el_.front();
                    el_.pop_front();
                }

                // Call the delegate without holding the mutex locked
                boost::apply_visitor (detail::event_caller<Klass> (delegate_),
                                      vtv);
            }
        }
    }

El operator()() de la clase actor ejecuta el código del hilo. He utilizado variables de condición porque me parecen más ricas semánticamente. El hilo básicamente extrae eventos de la cola de eventos y los ejecuta sobre el delegate. Como los eventos de la cola pueden ser de diferentes tipos (nótese que este punto es especialmente difícil en C++), hay que utilizar estructuras que permitan tratar diferentes tipos de eventos de forma genérica. Para eso he usado la construcción boost::apply_visitor de boost.variant. Con el uso de una clase especial, detail::event_caller, que se verá más abajo, se consigue llamar a la clase original, a los métodos process(Evento), para cada uno de los eventos recibidos.

    template <typename Event>
    self& operator<<(Event& e)
    {
        std::cout << “Received event” << std::endl;
        {
            boost::lock_guard<boost::mutex> lock (list_mutex_);
            el_.push_back (e);
        }

        // signal that a new event is available
        cond_.notify_one();

        return *this;
    }

El operador << se puede usar para enviar un evento al actor. Esta es una construcción que queda muy natural. Enviar un mensaje es diferente a realizar una llamada, aunque también se puede pensar en un mecanismo de llamada a función modificado. Al final, el envío de mensajes, como se verá después, será algo así como actor << Clase::Evento(valores);.

    void join()
    {
        thread_.join();
    }

    void stop()
    {
        stop_ = true;
        cond_.notify_one();
    }

private:
    Klass& delegate_;

    typedef std::deque<VariantType>  event_list;
    event_list el_;
    bool stop_; // stop?
    boost::thread thread_;

    boost::mutex mut_;
    boost::mutex list_mutex_;
    boost::condition_variable cond_;
};

Por completitud, aquí está la clase detail::event_caller. Es necesaria para visitar un tipo boost.variant a través de la función boost::apply_visitor. Simplemente llama a la función process() correspondiente.

namespace detail
{

template <typename Klass>
struct event_caller : public boost::static_visitor<>
{
    Klass& instance_;

    event_caller (Klass& i)
        : instance_ (i)
    {
    }

    template <typename T>
    void operator()( T const & operand ) const
    {
        instance_.process (operand);
    }
};
}

Llegamos a la clase sobre la que queremos construir el actor, llamada para este ejemplo TestClass. La clase define internamente un par de eventos (Event1 y Event2), y, como comentamos arriba, el tipo events_type, como un boost.variant de los diferentes eventos que puede recibir. Se pueden ver los métodos process() más abajo. En este caso la clase tiene métodos propios para retornar un actor interno. Esto no tiene por qué ser así, y como se ha visto, los actores son independientes de las clases de las que actúan en representación.

class TestClass
{
public:
    typedef actor<TestClass> actor_type;

    struct Event1
    {
        int data;
    };

    struct Event2
    {
        std::string ss;
    };

    // Obligatory
    typedef boost::variant< Event1, Event2 > events_type;

    actor_type& the_actor()
    {
        return *actor_;
    }

    // Ctor.
    TestClass()
        : actor_ (new actor_type (*this))
    {
    }

    ~TestClass()
    {
        actor_->stop();
        actor_->join();
        delete actor_;
    }

private:
    actor_type* actor_;

public:
    void process (Event1 const& e)
    {
        std::cout << “Processed event: “  << e.data << std::endl;
    }

    void process (Event2 const& e)
    {
        std::cout << “Processed event 2: “  << e.ss << std::endl;
    }
};

Por último, ¿cómo se usa este mecanismo de actores? Lo ideal es proveer de mecanismos que sean semánticamente ricos y que sigan el principio de mínima sorpresa. Con las clases de arriba podemos escribir código sencillo como el siguiente:

    TestClass::Event1 ev;
    ev.data = -2;

    TestClass::Event2 ev2;
    ev2.ss = “abcdef.”;

    TestClass tc;

    TestClass::actor_type& ac = tc.the_actor();

Primero se crean un par de eventos de los dos tipos que puede recibir la clase TestClass, y se obtiene el actor ac. Se puede usar ese actor para enviar eventos a la clase:

    // Send the event2
    ac << ev2;

    // Send message
    ac << ev;
    for (int i = 0; i < 2000; ++i)
    {
        ev.data = i;
        ac << ev;
        ac << ev2;
    }

Aquí se envía primero un evento de tipo Event1, y luego otro del tipo 2. Después se entra en un bucle que envía ambos mensajes, modificando el primer evento con un dato distinto. El programa va mostrando la salida de eventos de la clase en orden:

...
Processed event: 1996
Processed event 2: abcdef.
Processed event: 1997
Processed event 2: abcdef.
Processed event: 1998
Processed event 2: abcdef.
Processed event: 1999
Processed event 2: abcdef.

Un último apunte. Las diferencias con los actores de otros lenguajes dinámicos (Scala, por ejemplo), son que en estos lenguajes se puede especificar un procesado basado en máquinas de estados, como por ejemplo, cuando se recibe el evento 1, después sólo se puede recibir el evento 2. Esta máquina de estados se puede implementar. Es una primera implementación de prueba.

No dudéis en contactar conmigo para ideas o comentarios.

5/2/2010

C++ más rápido que C, o atoi versus boost.spirit v2

Filed under: General, español, código/code, free software/software libre — Diego Sevilla @ 20:42 — In English

Leo en C++ soup un test que hizo Alex Ott comparando la implementación de la función atoi de la librería de C con la versión de boost.spirit versión 2. En su artículo ponía de manifiesto que la versión de boost spirit es unas 3 veces más rápida. Sinceramente, es un resultado que alienta las nuevas técnicas de meta-programación basadas en templates para C++. Ya traté el tema hace un tiempo para mostrar cómo el compilador no generaba código para las sentencias de log cuando la clase se creaba con un parámetro de template false.

31/12/2009

(concat "Happy " (replace-regexp-in-string "2009" "2010" (format-time-string "%Y")) "!")

Filed under: General, english, código/code, free software/software libre — Diego Sevilla @ 20:23 — In English

Thanks to emacs-lisp :) . Valid at least the whole 2010 :) .

30/12/2009

Vídeos y clases sobre Scheme, LISP, Clojure, etc.

Filed under: english, español, código/code, free software/software libre — Diego Sevilla @ 15:57 — In English

Las encontré el otro día por casualidad. En la entrada del sitio web enlazan varias y contiene vídeos. En particular, me encantó ésta, sobre Scribble, el sistema de documentación de PLT Scheme, y que utiliza el módulo de presentaciones de DrScheme (slideshow) para crear una presentación inicial con gancho para la audiencia.

21/12/2009

SOAP, entre lo peor de la década

Filed under: english, español, crítica/critics, código/code — Diego Sevilla @ 20:09 — In English

Yo ya lo dije hace tiempo… Vía, que a su vez lo saca del “radar” de O’reilly. En ese artículo compara SOAP con CORBA, pero ni de lejos. Sobre todo porque la primera ha fracasado por su pésimo diseño arquitectural, mientras que CORBA fracasó por intereses económicos, no por que la tecnología estuviera mal diseñada.

El desafío de Arc, en Clojure

No conocía que Paul Graham, el inventor de un dialecto de Lisp llamado Arc, había lanzado un desafío. El desafío incluye escribir varias páginas web en cascada en la que la primera pide algo al usuario a través de un formulario. Al pulsar el botón de enviar del formulario, se muestra una segunda página con un enlace que lleva a una tercera que muestra lo que el usuario escribió. El ejemplo en Arc se supone que es extremadamente simple (gracias, por supuesto, a un framework Web escrito para el lenguaje en cuestión.

Tampoco sabía que se habían lanzado en masa a mostrar cómo resolver este problema en otros lenguajes, pero enlazo aquí la resolución en Clojure también porque esa página lleva enlaces a otros ejemplos de cómo resolverlo, y enlaces a los foros de Arc.

API design matters

Filed under: General, español, crítica/critics, código/code — Diego Sevilla @ 0:33 — In English

API design matters. Una versión distribuida de esto intento hacer en la asignatura de distribuidos. En sistemas distribuidos el API importa aún más.

27/11/2009

Java sucks

Filed under: english, español, crítica/critics, código/code — Diego Sevilla @ 0:51 — In English

Un poco antiguo, pero válido como el primer día. Java sucks.

25/11/2009

Auto-completado en Emacs

Filed under: español, código/code, free software/software libre — Diego Sevilla @ 10:39 — In English

Al hilo de mi anterior entrada sobre Emacs, me he puesto un rato a buscar unos enlaces y no quiero perderlos sobre auto-completado y ayudas semánticas (aparte del coloreado de sintaxis) en Emacs. La mayoría de estas cosas tengo que estudiarlas tranquilamente y leer los enlaces:

24/11/2009

Curiosidad con emacs

Filed under: español, crítica/critics, código/code, free software/software libre — Diego Sevilla @ 2:00 — In English

Por si no quedaba claro ya que emacs es (quizá) el mejor editor que se ha escrito nunca (quizá con el único que podría compararse es con vi, pero con ese no tento ganta experiencia), deciros que el otro día tenía que añadir 10 punteros, cada uno de un tipo, para una clase template en C++, y quería que tuvieran nombres también diferentes (t0 a t9). Sabía que en emacs tenía que ser sencillo insertar en la posición actual con emacs-lisp. Y efectivamente, con ESC : (escape y después dos puntos) te pregunta en la ventana del minibuffer (abajo) la expresión lisp que evaluar. Si se introduce lo siguiente:

(dotimes (i 10) (insert (concat "T" (number-to-string i) "* t" (number-to-string i) ";\n")))

se obtiene lo que quería. Básicamente es repetir 10 veces insertar una cadena que concatena los textos con el valor de convertir de número a cadena la variable i. Se podría haber añadido un “let” para asociar el valor de i como cadena y no calcularlo dos veces, pero así lo escribí rápidamente. ¿Alguien da más?

emacs

20/11/2009

Interesante artículo sobre DSLs internos en Java

Filed under: español, crítica/critics, código/code — Diego Sevilla @ 22:57 — In English

Buceando buscando información sobre DSLs (Domain Specific Languages, o lenguajes específicos de dominio) he encontrado un artículo en InfoQ muy interesante, de cómo implementarlos en Java. Tienen algunas ideas interesantes, pero es triste ver lo penosamente encorsetado que es Java comparado, por ejemplo, con C++ para implementar este tipo de lenguajes (no digamos con Ruby, por ejemplo). Comparando esto con conocidos DSLs internos en C++, como por ejemplo, Spirit o LuaBind, el soporte para DSLs en Java está un poco en pañales. ¿Se nota que no me gusta Java? :) Comparado con lenguajes serios como Scala y Clojure, que también se ejecutan en la JVM, Java es un lenguaje de juguete.

4/11/2009

Clojure

Filed under: General, español, código/code — Diego Sevilla @ 1:06 — In English

Como hace tiempo que no escribo en el blog, me voy a ir desquitando de cosas que quiero ir añadiendo para recordarlas en un futuro.

Clojure me interesa desde hace bastante tiempo por su mezcla entre lenguajes estilo Lisp dentro de la máquina virtual Java (como también Scala y unos cuantos otros, de los que hablaré más adelante). Por ahora he encontrado un link interesante que quiero guardar: 20 Clojure Links To Get You Up To Speed. Veinte enlaces a artículos interesantes sobre Clojure para iniciarse rápidamente. Además, clojure está de enhorabuena en su versión 2 :)

2/11/2009

Sobre comentarios en código

Filed under: General, english, español, crítica/critics, blogging, código/code — Diego Sevilla @ 23:10 — In English

Al hilo de lo de ayer, he encontrado otras referencias interesantes:

  • Coding without comments y Code Tells You How, Comments Tell You Why, de Jeff Atwood, con comentarios sobre el conocido como literate programming, introducido por Knuth para implementar, entre otros, su TeX. En el último artículo introduce una cita que me parece muy ilustrativa:

    Programs must be written for people to read, and only incidentally for machines to execute.

  • Después, una reflexión de si la capacidad o incapacidad para escribir en tu idioma materno afecta a tus capacidades de programación: Does Bad Writing Reflect Poor Programming Skills?, lo cual tampoco había pensado nunca, pero es una reflexión válida. Como batallita, comentaré que una de las preguntas que más me sorprendió de cuando hice mi entrevista en Google fue que uno de los que me entrevistaron directamente me preguntó «Virtual methods in C++?», y yo lo miré como diciendo… ¿qué? Me estaba pidiendo, por supuesto, que se lo explicara. Perfectamente, una cosa tan sencilla no iba a tener problema en explicárselo. Sin embargo, me puse a contárselo y no me salían las palabras exactas… ¿Habré hecho yo métodos virtuales en mi vida?, me preguntaba yo… unos cuantos miles… en fin…
  • Finalmente, al hilo de los comentarios en el código, unas cuantas razones de por qué los programadores no comentan su código, entre otras, porque “I’m the greatest programmer ever!”:)

Todo esto se puede adornar añadiendo cuestiones como las pruebas unitarias, etc. Todo se andará.

Práctica de la programación

Filed under: General, español, blogging, código/code — Diego Sevilla @ 0:43 — In English

Reconozco que nunca lo había pensado. Para programar bien, igual que con cualquier otro arte, hay que practicar. He encontrado este artículo, que me ha parecido muy interesante: Practicing Programming. El artículo incluye también trucos o indicaciones de qué practicar y cómo. Algunos de los consejos no me cuadran mucho porque se refieren a cómo realizar entrevistas a programadores, que también es un tópico interesante, pero a mí no me interesa tanto.

En un momento dado, compara el ser contratado por una u otra empresa de informática como programador a estar jugando en una liga de fútbol americano (NFL). ¿Es importante que el jugador (programador) esté bien entrenado?

[…] is it good enough for him to be in good shape? Hardly. Maybe it’s sufficient for a position on a high-school junior-varsity team, but Amazon’s supposed to be more like the NFL than high school J.V., isn’t it? I think so.

O dicho de otro modo. Si queremos terminar en una empresa seria, o aspirar a lo máximo, hay que tener al día nuestra práctica.

Al hilo de esto, y gracias a los comentarios, he encontrado también un sitio dedicado a esa práctica de la programación, llamado «CodeKata» (al estilo de las tablas de artes marciales), y un artículo interesantísimo que critica y es contrapuesto a los típicos títulos «Aprenda XXX en 24 horas», o en pocos días, para el caso. El artículo, «Teach Yourself Programming in Ten Years», también en español, muestra que hay estudios que demuestran que para obtener una destreza suficiente en una disciplina hacen falta unos diez años. Esto me ha recordado también a una magnífica charla que dio Michi Henning por el 2004 sobre las falacias de la computación, que siempre estará al día… (aquí con comentarios).

22/4/2009

Blogs para estar al día de C++

Filed under: español, código/code — Diego Sevilla @ 19:30 — In English

Se admiten sugerencias, y los pongo aquí para tenerlos accesibles:

¿Más sugerencias?

Cálculo de la FFT con metaprogramación en C++

Filed under: english, español, código/code — Diego Sevilla @ 17:25 — In English

Me ha parecido curioso. C++ es muy útil para poner al compilador a trabajar para generar de antemano valores que de otra manera tendrían que estar calculados por una función. Como un ejemplo extremo, se puede ver una implementación de la función FFT (transformación rápida de Fourier) en C++ con metaprogramación. Esta implementación funciona unas 4 veces más rápido que el algoritmo, ya que todo el trabajo de precálculo lo hace el compilador.

23/3/2009

Google Tech Talks

Filed under: english, español, blogging, código/code — Diego Sevilla @ 17:12 — In English

A veces me gusta ir viendo videos del Google Tech Talks, charlas divulgativas de nuevas tecnologías o tecnologías actuales, pero desde un punto de vista innovador muchas veces. Apunto aquí para tener de referencia charlas que me interesan, relacionadas con el trabajo que estoy haciendo ahora después de la tesis, para cuando tenga tiempo de verlas, y por si pueden interesar a alguien más:

Hay otras que quiero buscar tranquilamente después, como una sobre el mecanismo de concept_check (comprobación de conceptos) en c++1x, que añadiré cuando encuentre.

10/3/2009

identi.ca

Filed under: General, english, español, blogging, código/code, free software/software libre — Diego Sevilla @ 1:18 — In English

Me he registrado en identi.ca (http://identi.ca/dsevilla) porque me ha gustado más la filosofía, al menos más libre que twitter. Además, el sitio parece estar más orientado a programadores: GNU emacs, debian, etc.

More C++ idioms wikibook

Filed under: General, english, español, código/code — Diego Sevilla @ 1:02 — In English

Gran referencia de patrones de código de C++ en un Wikibook.

Next Page »

Creative Commons License
This work is licensed under a Creative Commons License.
EWWV  AWStats  Site Meter 23 queries. 0.146 seconds. Powered by WordPress
406021 email messages processed in this box. 10858 were spam

0