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 :)

7/10/2010

Nuevo dominio para la Cátedra SAES

Filed under: General, español, free software/software libre — Diego Sevilla @ 13:17 — In English

Como alguna vez he escrito por aquí, colaboramos con la empresa SAES de Cartagena y San Fernando para realizar investigación dentro del marco de la Cátedra SAES/UMU de software libre, aplicaciones críticas y en tiempo real. Sólo un pequeño comentario para decir que hemos aunado las direcciones de la cátedra y hemos creado un dominio .org: www.catedrasaes.org. Dentro de él podéis encontrar la lista, incompleta todavía, de proyectos en los que estamos trabajando, e incluso un blog.

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

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.

11/12/2009

Mark Volkmann: Clojure

Filed under: english, español, free software/software libre — Diego Sevilla @ 22:06 — In English

Interesante página sobre clojure..

25/11/2009

En Karmic: Increíble

Filed under: General, español, free software/software libre — Diego Sevilla @ 21:01 — In English

Sólo he tenido que quitar la opción skip-bdb de mysqld, que parece que no le gusta. Por lo demás, absolutamente todo funcionando sin problemas y actualizado.

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

5/11/2009

Días Caldum’09

Filed under: General, español, blogging, free software/software libre — Diego Sevilla @ 15:22 — In English

Por estos días se celebran los días caldum en la Facultad de Informática y esta tarde me han pedido que participe en la mesa redonda sobre software libre (a las 18:30) representando a la cátedra SAES de software libre. Después pongo las transparencias. La mesa redonda supongo que irá sobre la influencia o implantación del software libre en Murcia. En mi caso, explicaré cómo una empresa de la región apuesta por él, y qué sinergias se pueden extraer.

Actualización: Las transparencias aquí (PDF).

20/4/2009

10 tutoriales interesantes de Blender

Filed under: english, español, fotografía/photo, free software/software libre — Diego Sevilla @ 15:54 — In English

Vía.

30/3/2009

Linux for designers

Filed under: english, español, blogging, fotografía/photo, free software/software libre — Diego Sevilla @ 0:01 — In English

Interesante blog: Novedades de Linux (en realidad software libre en general) para diseñadores gráficos.

21/3/2009

Ext4

Filed under: General, español, free software/software libre — Diego Sevilla @ 1:54 — In English

El nuevo núcleo 2.6.28 que trae el Ubuntu Jaunty (disponible también en versiones nightly) permite montar sistemas de ficheros ext4 con la ventaja de los conocidos “extents”. Esta característica mejora la gestión de nodos-i del sistema de ficheros, intentando, por un lado, agrupar al máximo los bloques de un fichero en bloques consecutivos (lo cual también mejora el desempeño del disco), y, por otro, reducir el tamaño de los nodos-i y descriptores de bloques de ficheros usando una sintaxis del estilo: empieza en el bloque X y posee Y bloques consecutivos (parecido a la codificación de matrices sparse, que al fin y al cabo son lo que son los ficheros…), lo que ofrece una especificación mucho más compacta de los metadatos del fichero.

Aunque hay algunos tutoriales de cómo hacer el cambio de ext3 a ext4, siempre da algún tipo de quebradero de cabeza. Contaré más o menos cómo lo he hecho y qué problemas he tenido, para hacer más fácil la conversión.

Normalmente la conversión funciona sin problemas. Ext4 es compatible con ext3 en casi todos los aspectos, salvo en el “extents”, precisamente. Así que una vez establecida esta capacidad, el sistema ya no se puede leer normalmente como ext2 ó ext3. Otra característica de la implementación tal y como está ahora es que el “paso” a extents no se hace automáticamente para todos los ficheros, sino que sólo sucede cuando se crea un nuevo fichero. En siguientes versiones del núcleo se dispondrá de un demonio que irá pasando paulatinamente todos los ficheros al formato extents en segundo plano.

Teniendo un núcleo 2.6.28 bien configurado, se puede pasar a convertir a ext4. Para ello, según dictan los tutoriales, hay que, una vez desmontado el sistema de ficheros (o montado como sólo lectura), ejecutar lo siguiente:

tune2fs -O extents,uninit_bg,dir_index dispositivo/partición

Las otras opciones ayudan a que fsck sea más rápido en su ejecución y a que los directorios estén indexados con árboles B. A continuación hay que ejecutar fsck obligatoriamente para adaptar el sistema de ficheros:

fsck -pf dispositivo/partición

(la opción -p arregla todos los inconvenientes encontrados, es decir, realiza la actualización). Muestra algunas indicaciones de que reconstruye ciertos índices internos. Estos mensajes son normales.

Después, es importante, antes de reiniciar, tener en cuenta modificar el fichero /etc/fstab para indicar el tipo de los ficheros.

El gestor de arranque también es importante. Tanto grub (versión >= 0.97) como grub2 aceptan ext4 con extents. Ahora bien, al menos en grub, es importante tener actualizadas las diferentes etapas de arranque. En mi caso, por ejemplo, he tenido problemas porque las distintas etapas correspondían a una versión de grub que no soportaba extents, y el sistema no arrancaba. Así, como root hay que instalar (por si acaso) la última versión de grub en el sector de arranque (o el MBR, dependiendo de la instalación) del disco de arranque:

/usr/sbin/grub-install dispositivo

(en mi caso, el dispositivo era /dev/sdb, aunque normalmente suele ser /dev/sda en una instalación normal).

El resultado, después del arranque, en mi caso:

$ mount
/dev/sdb4 on / type ext4 (rw,relatime,errors=remount-ro)
/dev/sdb3 on /home type ext4 (rw,relatime)

Como se ha dicho, el paso a extents no es automático, y se debe hacer copiando los ficheros (no moviéndolos), o con rsync o tar entre directorios, entre otros mecanismos de sobra conocidos. Para comprobar el estado de algún fichero, se puede hacer lo siguiente:

$ sudo filefrag yo.jpg
yo.jpg: 28 extents found, perfection would be 1 extent

Conforme el sistema se llena, es más difícil alcanzar la perfección… pero se puede uno acercar :) . Por ejemplo:

$ mv yo.jpg 0yo.jpg
$ cp 0yo.jpg yo.jpg
$ rm 0yo.jpg
$ sudo filefrag yo.jpg
yo.jpg: 1 extent found

En este caso ha habido suerte.

¿El resultado? Al menos en mi caso, y de forma subjetiva, el sistema va mucho más suelto en los accesos a disco, incluso sin pasar muchos ficheros a extents. Ext4 lleva mejoras internas de la implementación que hacen más rápido el acceso, y los extents también mejorarán, porque todos los ficheros creados a partir de ese momento utilizan ese mecanismo.

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.

9/3/2009

gedit -

Filed under: General, español, crítica/critics, free software/software libre — Diego Sevilla @ 23:11 — In English

Yo todavía no me puedo explicar cómo es posible que no funcione el entubado de la entrada estándar en gedit:

comando | gedit -

Incluso en vim/gvim, y también con el editor de programadores de Mac (el textmate). ¿Cómo es posible que gedit no lo permita? Emacs tampoco lo permite… muy mal…

4/2/2009

Más avances: Cátedra SAES-UMU

Como un avance inédito (se firma mañana), os diré que otra cosa que me ha tenido muy ocupado los últimos meses (en realidad años) es lo que hemos llamado la “Cátedra SAES-UMU”. Esta cátedra significa un apoyo monetario a la investigación que una empresa privada, en este caso la Sociedad Autónoma de Electrónica Submarina (SAES), ofrece a la Universidad de Murcia a través de unos promotores de la misma (en este caso Gregorio Martínez y yo mismo). El acuerdo será por dos años, y pronto prepararemos una página web con algunos resultados que estamos obteniendo en nuestras investigaciones.

La cátedra se financia por la empresa, y permite que nosotros contratemos a personal que realiza investigaciones, tesis, etc. (camos, la labor de la Universidad), mientras que la empresa se beneficia de que orientemos nuestras investigaciones hacia temas que le sean de interés. Esta sinergia universidad-empresa es el fin último de la Universidad, que tiene que proveer conocimiento básico que finalmente se pueda aplicar a una empresa.

Personalmente estoy muy contento (y también orgulloso en cierto grado), como sé que lo está Gregorio, de que esta empresa haya confiado en nosotros para ofrecernos esta oportunidad, también teniendo en cuenta que es la cátedra de más cuantía económica que se ha realizado nunca en la Universidad de Murcia. Esta confianza mutua se ha ido fraguando a lo largo de tres años de colaboraciones puntuales con la empresa en tópicos relacionados con el modelado de aplicaciones, software libre, programación en C++, programación distribuida y CORBA (sí, chichos, por extraño que parezca), etc.

La firma la realizará el Rector de la Universidad de Murcia junto con el director general de SAES mañana miércoles 4 a las 10 de la mañana en el edificio de convalecencia de Murcia. Irá también la prensa, así que no descarto que aparezca en los periódicos.

Nada más por hoy que mañana tenemos un acto importante…

3/2/2009

Avanzando temas: Tesis

Bueno, aquellos que me conocéis o que estáis en mi círculo más cercano sabréis que el año pasado estuve bastante ocupado, dejando a un lado casi a mis amistades, aficiones, … todo lo que no fuera la tesis.

El trabajo de escribirla e implementarla fue inmenso para mí. Quizá otras personas tengan más facilidad o no les cause tanto estrés y cansancio, pero a mí me dejó exhausto. Tanto que cuando la terminé ya no quiero ni volver a verla.

Sí me gustaría, no obstante ir comentando poco a poco cómo la hice, los puntos importantes, y mostrar la propia tesis, que al menos, si alguien la lee, o alguna parte de ella, que al menos tenga la sensación de que sirve para algo…

La presentación de la misma fue el día 4 de noviembre, y todo fue bien. Menos mal, después de tanto trabajo. Parece que les gustó a los miembros del tribunal (que me calificaron con Summa Cum Laude por unanimidad).

Por ahora os dejo una página que hice para mostar la tesis a los miembros del tribunal. La tesis está en PDF (ojo, 64MB), y también página a página. Que la disfrutéis. Me guardo para después explicar un poco de la tesis en sí misma y de cómo la fui desarrollando.

5/10/2008

Compilando inkscape y usando spiro

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

Hoy Emma se sentía algo malita y no hemos salido. He aprovechado para jugar un poco con la versión SVN de inkscape, porque quería probar la funcionalidad «spiro» (que había visto ya en el screencast de Heathernx). Me he descargado el código, lo he configurado y lo he compilado sin problemas.

Sin embargo, al ejecutarlo, daba un error muy extraño. Probando un rato he encontrado una manera de arreglarlo, aunque no sé si es perfecta. El programa funciona sin problemas lo que he probado. Aquí pongo el patch por si alguien quiere probar:

$ svn diff
Index: src/live_effects/lpe-knot.cpp
===================================================================
--- src/live_effects/lpe-knot.cpp	(revisión: 19971)
+++ src/live_effects/lpe-knot.cpp	(copia de trabajo)
@@ -47,7 +47,7 @@
 //remove an interval from an union of intervals.
 //TODO: is it worth moving it to 2Geom?
 static
-std::vector<Geom::Interval> complementOf(Geom::Interval I, std::vector<Geom::Interval> domain){
+std::vector<Geom::Interval> complementOf(Geom::Interval I, std::vector<Geom::Interval>& domain){
     std::vector<Geom::Interval> ret;
     double min = domain.front().min();
     double max = domain.back().max();
Index: src/sp-item.cpp
===================================================================
--- src/sp-item.cpp	(revisión: 19971)
+++ src/sp-item.cpp	(copia de trabajo)
@@ -1129,7 +1129,9 @@
         NR_ARENA_ITEM_SET_DATA(ai, item);
         NRRect item_bbox;
         sp_item_invoke_bbox(item, &item_bbox, Geom::identity(), TRUE, SPItem::GEOMETRIC_BBOX);
-        boost::optional<Geom::Rect> i_bbox = item_bbox;
+        Geom::Rect r(Geom::Point(item_bbox.x0,item_bbox.y0),
+                     Geom::Point( item_bbox.x1, item_bbox.y1));
+        boost::optional<Geom::Rect> i_bbox = r;
         nr_arena_item_set_item_bbox(ai, i_bbox);
     }

(como fichero patch).

El primer cambio ha sido una optimización rápida que he visto (paso por referencia en vez de por copia del vector), y el segundo es para hacer que funcione.

Con esta versión, es muy sencillo realizar filigranas como la que hice en 1 minuto:

Al contrario de la versión 0.46 o las de desarrollo que había probado hasta ahora, los efectos del trayecto (a la derecha) se pueden almacenar, con lo que puedo añadir los splines de spiro y un patrón a lo largo del trayecto. Gran programa Inkscape. Me ha solucionado las figuras de la tesis y tantas otras cosas…

Me he dado cuenta de que no he puesto más datos de cómo descargar y compilar. Ahí van:

$ svn co https://inkscape.svn.sourceforge.net/svnroot/inkscape/inkscape/trunk inkscape
$ cd inkscape
$ patch -p0 < patch
patching file src/live_effects/lpe-knot.cpp
patching file src/sp-item.cpp
$ ./autogen.sh
$ ./configure --prefix=XXX
$ make -jY
$ make install

donde XXX es el directorio donde queráis instalarlo (por defecto /usr/local), e Y el número de proecesadores (cores) que queráis utilizar para compilar. Hacen falta bastantes librerías, por lo que habrá que ir instalándolas conforme las pida el script configure.

Actualización 6/10: Parece que ya han arreglado el falllo. El patch no es necesario, salvo quizá la primera parte, que es una optimización. Lo propondré como posible parche.

Next Page »

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

0