La empresa precursora de la catalogación de contenidos en Internet, Yahoo!, te ofrece un servicio gratuito con el cual podrás construir elaborados resultados a partir de uno o más feeds RSS, Atom o RDF. Actualmente la práctica totalidad de los sitios web que se renuevan con cierta frecuencia, como los que ofrecen noticias de actualidad, las bitácoras y las de muchas empresas, disponen de un servicio que facilita los nuevos contenidos, en versión completa o abreviada, en los formatos RSS, Atom o RDF. De esta forma es posible obtenerlos de manera agregada, con aplicaciones específicas, sin necesidad de visitar cada una de las páginas de forma individual. El resultado es un ahorro de tiempo y la obtención de los contenidos que interesan o, al menos, que proceden de los sitios que interesan. Es habitual que mediante nuestro lector RSS estemos suscritos a múltiples feeds de diferentes temas que nos interesen, obteniendo la suma de contenidos de todos ellos. Con Yahoo! Pipes es posible ir un paso más allá, siendo la agregación de contenidos solamente una de sus posibilidades. Lo más interesante son los filtros y el hecho de que el resultado obtenido de una fuente puede ser utilizado para buscar contenidos en otra.
Yahoo! Pipes es una aplicación tipo AJAX, lo que significa que solamente necesitarás de tu navegador para ejecutarla. Basta con introducir el URL http://pipes.yahoo.com e iniciar sesión, utilizando para ello las credenciales de Yahoo! si cuentas con ellas. Tendrás un usuario y una contraseña si, por ejemplo, utilizas Yahoo! Groups. De lo contrario, no tienes más que registrarte en ese mismo momento, es un proceso gratuito, sencillo y rápido.
La aplicación consta funcionalmente de dos partes bien diferenciadas: un diseñador de Pipes, que aprenderás a utilizar si lees el resto de este artículo, y un motor que ejecuta esas Pipes para ofrecerte el resultado que generen. Una Pipe es una tubería, de ahí que hagamos referencia a ellas en femenino.
El diseñador facilita la construcción de las Pipes a partir de una serie de componentes prefabricados, que irás colocando sobre una superficie y conectando entre sí mediante la técnica de arrastrar y soltar. Cada componente tiene una finalidad concreta: recuperar el contenido de una fuente, ordenar las entradas, unir entradas de varios feeds, traducir los contenidos, filtrarlos, etc.
La ejecución de una Pipe llevará a cabo todas las tareas establecidas en el diseño, generando un resultado que será el que se muestre en el navegador. En el sitio de Yahoo! Pipes hay infinidad de diseños hechos por otros usuarios, diseños que pueden ser tanto ejecutados como clonados para crear otros a partir de ellos, modificándolos o ampliándolos.
Para ejecutar una Pipe no tendrás más que elegirla, de la lista que se ofrece en el propio sitio antes indicado, como harías clic en cualquier hipervínculo. La ejecución del diseñador, por el contrario, exige que nuestro navegador tenga unas ciertas características. Si utilizas Mozilla Firefox o Internet Explorer 7 o posterior no tendrás ningún problema, pero algunas antiguas versiones de navegadores, como Opera, no son capaces de ejecutar correctamente esta aplicación AJAX o, dicho de otra forma, la aplicación no está diseñada para funcionar adecuadamente en ese navegador.
Lo primero que debes hacer, por tanto, es abrir tu navegador, ir a Yahoo! Pipes, hacer clic en el enlace Sign in que está en la parte superior derecha de la página e introducir tu nombre de usuario y contraseña para iniciar sesión. A partir de este momento ya puedes tanto examinar diseños de otros usuarios como crear los tuyos propios. Estos últimos estarán siempre accesibles en el apartado My Pipes.
El concepto de tubería o (pipe) procede del sistema operativo UNIX. La denominación procede de la analogía clara entre un canal de comunicación, que envía los resultados que produce un programa hasta la entrada de otro, y una tubería que conecta esos mismos dos elementos, trasladando lo que sale de uno hasta otro. Ese proceso puede repetirse, de forma que la salida del segundo programa puede ser a su vez, mediante otra tubería, utilizada como entrada por un tercer programa.
Yahoo! Pipes traslada este mecanismo de comunicación entre procesos a la web, pero básicamente no hay diferencias respecto al funcionamiento de una serie de programas conectados entre sí mediante tuberías. La diferencia más obvia es que no es necesario utilizar una línea de comandos para escribir los nombres de los programas y conectarlos, porque esta tarea se efectúa visualmente desde el diseñador de Pipes.
Un comando Unix como cat temp1 temp2 | sort -n | head -5, asumiendo que los archivos temp1 y temp2 almacenan temperaturas de dos días de un cierto lugar, daría como resultado las cinco temperaturas más bajas. El comando se compone de tres partes conectadas entre sí mediante el símbolo de tubería de Unix, de forma que la salida de cat se lleva hasta sort y la de este programa hasta head.
Una vez que tienes una idea general de cómo funciona Pipes, lo que más te interesará será aprender a utilizar esta aplicación para hacer tus propios diseños. Comenzarás con un caso bastante sencillo, en el que vas a agregar las noticias de dos sitios que visitas habitualmente para obtenerlas combinadamente en una misma página. A continuación, en pasos posteriores, aprenderás a establecer el orden en que aparecen las entradas resultantes y a filtrarlas.
Los sitios seleccionados están relacionados con la paleontología, evolución y temas similares. Lo primero que tienes que hacer es ir a esas páginas, o cualesquiera otras que visites con asiduidad, y localizar el enlace que te facilita el feed de noticias en formato RSS, Atom o RDF. Anota el URL, para utilizarlo después en Pipes, o bien cópialo al portapapeles y de esta forma podrás pegarlo directamente cuando lo necesites.
A continuación inicia sesión en Yahoo! Pipes, haz clic en el enlace My Pipes y a continuación selecciona la opción Create a pipe. Si es la primera vez que utilizas Pipes posiblemente el diseñador te invitará a que veas cómo están construidos algunos ejemplos, todos ellos en inglés. Haz clic en el botón OK que hay en la parte inferior de la ventana de bienvenida, de esta forma te encontrarás ante el editor de Pipes.
El núcleo de Yahoo! Pipes lo forma el editor o diseñador que facilita la composición y manipulación de los flujos de contenidos. Este editor, como se aprecia en la figura inferior, divide el espacio de trabajo en varios paneles. En la parte superior se disponen dos grupos de botones que facilitan tareas que irás conociendo poco a poco.
El panel de la izquierda contiene los distintos módulos o componentes que puedes usar en los diseños, agrupados según su funcionalidad. El grupo abierto por defecto es Sources, en el que se encuentran los módulos encargados de obtener los contenidos desde Yahoo! Search, Google, Flickr o cualquier otro lugar que te interese. La parte inferior de este mismo panel contendrá una descripción del módulo que se encuentre seleccionado en el editor.
La zona central del editor, que muestra el mensaje drag modules here, será tu superficie de trabajo. Sobre ella irás colocando los módulos, moviéndolos a donde te interese y estableciendo las conexiones adecuadas entre ellos.
Debajo de la superficie del diseñador está el área de depuración, en la que aparecerán mensajes diversos a medida que trabajes sobre el proyecto. Al probar la Pipe, por ejemplo, en esta zona se indicará el número de entradas recuperadas y sus títulos.
Fíjate en que los distintos paneles del editor están separados entre sí por unos bordes que puedes ajustar según necesites, ampliando o reduciendo el espacio asignado a cada zona. Por regla general, especialmente cuando tus diseños empiecen a ser de cierta complejidad, siempre necesitarás el mayor espacio posible en la superficie de trabajo, para poder ir colocando los módulos y conectándolos entre sí.
Un elemento imprescindible en el diseño de cualquier Pipe será el módulo, o módulos puesto que pueden ser varios, que aporte el contenido sobre el que se trabajará para generar el resultado. Estos módulos se encuentra en el grupo Sources y se caracterizan porque establecen una comunicación con un servidor remoto, efectúan una solicitud y almacenan la respuesta obtenida para su posterior tratamiento.
De los módulos de contenido existentes cuatro de ellos son de carácter específico, en el sentido de que están preconfigurados para trabajar sobre un cierto servicio: Yahoo! Search, Yahoo! Local, Google Base y Flickr. Con ellos es posible efectuar una búsqueda en la web, localizar viviendas, trabajos o imágenes, respectivamente. Estos módulos, al ser introducidos en un diseño, solicitan directamente el tipo de bien que quiere localizarse, la distancia a la que debe encontrarse de un punto, el número de imágenes a obtener, etc. Muchos de esos datos se pueden introducir manualmente, en los recuadros de texto dispuestos a tal fin, o bien se recuperados de otros módulos.
Partiendo de la superficie vacía que se obtiene al iniciar un nuevo proyecto, lo primero que vas a hacer es recuperar las entradas de las bitácoras en que estás interesado. Para ello recurrirás al módulo Fetch que, a diferencia de los restantes del grupo Sources, es de tipo genérico, por lo que permite obtener contenidos de cualquier fuente. Haz clic sobre el botón Fetch para agregar el módulo al diseño.
Los componentes de Pipes aparecen como pequeñas ventanas flotantes sobre la superficie de trabajo, con un título y sus botones para minimizar y cerrar. Puedes colocarlos donde quieras sencillamente arrastrándolos, como harías con cualquier ventana. Observa que al mismo tiempo que el módulo Fetch ha aparecido otro llamado Pipe Output. Éste será el encargado de recoger los resultados del diseño y enviarlos al navegador.
En principio el módulo Fetch tiene un apartado en el que puede introducirse el URL del que se obtendrán las entradas. Según se indicó antes, puedes copiarlo en el portapapeles desde la página original y pegarlo aquí. Puesto que te interesa recuperar noticias de dos sitios, tendrás que hacer clic en el botón que muestra un icono con el signo +, a la izquierda del título URL, para añadir un nuevo URL. Repite la operación para añadir tantas fuentes como quieras.
En este momento tu diseño se compone de dos módulos, uno que recupera los contenidos y otro que es el encargado de enviar el resultado al navegador, pero no existe conexión alguna entre ellos. Si ejecutases la Pipe en este momento, por tanto, no obtendrías nada.
Todos los módulos de Yahoo! Pipes cuentan con uno o más puntos de conexión, en unas ocasiones de entrada, situados en la parte superior, y en otros de salida, colocados en la parte inferior de la ventana que representa al módulo. Hay otros conectores, de menor tamaño, que aparecen en el interior de las ventanas y que hacen posible que campos como el URL del que se obtendrán los contenidos, que ahora has escrito manualmente, puedan ser obtenidos de otros módulos.
La conexión entre dos módulos cualesquiera, o para ser más exactos entre dos conectores, se lleva a cabo mediante la técnica de arrastrar y soltar. En este caso puedes colocar el puntero del ratón sobre el conector que hay en la parte inferior del módulo Fetch, pulsar el botón principal y, sin soltarlo, desplazar el puntero hasta el conector de Pipe Output. Dicho conector aparecerá como iluminado al acercar el puntero del ratón. Al soltar verás cómo se establece la conexión.
Con los pasos dados hasta ahora ya tienes completado tu diseño, no hay más que guardarlo y comprobar que, en efecto, genera el resultado que buscabas. Haz clic en el botón Save que hay en la parte superior derecha del editor. Verás aparecer una ventana flotante en la que se solicita el nombre de la nueva Pipe, escríbelo y haz clic de nuevo en Save. Tu diseño ya está guardado.
El nombre que hayas dado a tu proyecto aparecerá ahora como título de la página actual del editor, en sustitución del anterior untitled. Además, a la derecha de esa pestaña ahora verás que se muestra un enlace con el título Pipe Preview. Utilízalo para ver el resultado que genera esta Pipe. Deberías ver una página en la que aparece el título de la Pipe, una serie de opciones, el diseño simplificado en el margen izquierdo y los contenidos recuperados. Desde esta página puedes modificar el diseño, utilizarlo como base para otros, publicarlo para que puedan acceder al mismo otros usuarios, etc.
En este primer diseño te has limitado a tomar contenidos de dos o más sitios y obtenerlos conjuntamente en una página propia, algo sencillo pero que ya te ahorrará el tener que visitar individualmente cada uno de esos sitios. Yahoo! Pipes, sin embargo, puede hacer mucho más por ti. El conjunto posiblemente más potente de módulos que ofrece Yahoo! Pipes se encuentra en el grupo Operators, con componentes que permiten ordenar las entradas, unir entradas de varios módulos fuente, eliminar los elementos repetidos, filtrar las entradas para bloquear o permitir las que cumplan ciertos criterios, traducir las entradas a otros idiomas, etc.
Aunque puedes partir de un nuevo diseño para probar algunos de estos módulos, en los pasos siguientes continuaremos con el proyecto anterior, sobre el que efectuaremos cambios discretos para adecuar el resultado que genera. Concretamente vas a establecer el orden en que deben aparecer las entradas, así como a establecer un filtro que elimine aquellas que traten temas que no te interesan.
Los filtros de Yahoo! Pipes, como los de Unix, son pequeños programas que actúan a modo de embudos o máquinas de transformación. Sobre un filtro se vuelca un contenido, que puede proceder de cualquier otro módulo, sobre el que va a trabajarse para producir una salida o resultado. El trabajo puede consistir en cambiar el orden de las entradas, eliminar aquellas en las que se encuentra un cierto texto, modificar el propio contenido de las entradas, etc.
En ocasiones dichos programas no son tan pequeños. El módulo BabelFish, por ejemplo, es capaz de traducir la entrada que se le facilite entre decenas de idiomas, generando un resultado que se puede enviar directamente al módulo de salida o bien ser procesado con anterioridad en otros módulos.
En el apartado Documentation de Yahoo! Pipes, concretamente en el URL http://pipes.yahoo.com/docs/modules, puedes encontrar una descripción detallada de cada uno de los módulos que puedes usar.
Puesto que vas a cambiar la Pipe que habías creado anteriormente, deberás volver a abrirla en el editor de Yahoo! Pipes. También puedes optar por clonar dicho diseño y crear otro nuevo a partir de él. Una opción más, interesante cuando los proyectos comienzan a ser complejos, consiste en utilizar como un módulo más, Pipes que se hayan creado con anterioridad. De todas estas opciones, en nuestro caso vamos a optar por la modificación directa dada la extrema sencillez del diseño.
A fin de ordenar y filtrar las entradas que se recuperen mediante el módulo Fetch, será necesario interrumpir la conexión directa que hay entre dicho módulo y el Pipe Output. De lo contrario no podrías intercalar otros módulos entre ellos. Para cortar una conexión haz clic sobre uno de los conectores, da igual que sea un extremo u otro de la tubería. Verás que aparece un icono con el dibujo de unas tijeras. Haz clic sobre él y la conexión desaparecerá.
Según que el flujo de entradas obtenido mediante módulos como Fetch proceda de una fuente RSS, Atom o RDF, cada entrada constará de unos ciertos campos entre los que suelen encontrarse el título, la fecha de publicación, una descripción o un hipervínculo asociado. Los valores de cualquiera de esos campos pueden ser utilizados para cambiar el orden de las entradas o bien para filtrarlas.
El módulo encargado de ordenar las entradas es Sort y, como el resto de operadores de Yahoo! Pipes, lo puedes encontrar en el grupo Operators. Haz clic sobre este componente y colócalo en tu diseño, entre el módulo Fetch y el módulo Pipe Output, estableciendo las conexiones adecuadas para que los contenidos recuperados por el primero pasen por Sort y de éste vayan a la salida.
Una vez establecida la conexión, en la lista de la izquierda del módulo Sort aparecerán los campos por lo que es posible ordenar. No tienes más que abrirla y seleccionar el que te interese. En la lista de la derecha puedes elegir entre un orden ascendente, de menor a mayor, o bien descendente, de mayor a menor.
En caso de que te interese, puedes ordenar el flujo de entradas por más de un campo. Para ello haz clic en el icono que hay a la izquierda de Sort by y verás cómo aparece una segunda fila con las mismas dos listas que acabamos de explicarte. De esta forma es posible, por ejemplo, ordenar las entradas por fecha y, dentro de cada fecha, alfabéticamente por título.
Por regla general no siempre te interesarán todas las noticias procedentes de un cierto sitio, aunque la temática de éste sí te guste. Es más, puede darse el caso de que ciertos contenidos concretos no te interesen lo más mínimo, por lo que podrías ahorrar tiempo si se eliminasen durante el proceso llevado a cabo por Pipes. Para ello no hay más que agregar un filtro y definir las reglas apropiadas.
El modulo que necesitas en este caso es Filter, que puedes colocar antes o después de ordenar las entradas obtenidas con Fetch. Si lo pones antes, de forma que la salida de Fetch vaya a Filter y la de éste a Sort, eliminarás lo que no te interesa antes de proceder a ordenar las entradas, por lo que será necesario menos tiempo para efectuar la ordenación.
Un filtro consta de una o más reglas que determinarán qué entradas se permiten o se bloquean. En la primera lista del módulo Filter tendrás que elegir entre Block: bloquear las entradas, o Permit: permitir las entradas, que cumplan los criterios que definirás a continuación. Suponiendo que no quieras obtener en los resultados las entradas en cuyo título se haga referencia a un cierto tema, elige el elemento Block.
En la lista items that match tendrás que elegir entre all o any. Si eliges all se eliminarán aquellas entradas para las que se cumplan todas las reglas indicadas debajo. De esta forma podrías, por ejemplo, bloquear las noticias que contengan una cierta palabra en el título y, además, la fecha sea anterior a una dada. Con la opción any se eliminaría la entrada en el momento en que se cumpla cualquiera de las reglas, en dicho ejemplo cuando contuviese el término en el título, fuese anterior a la fecha indicada o ambas.
Cada regla se compone de uno de los campos con que cuentan las entradas, un operador y un valor de referencia. El operador puede comprobar si el campo contiene o no contiene un cierto texto, si su valor es superior o inferior a un valor determinado o incluso utilizar una expresión regular. En la imagen puedes ver cómo se ha configurado el módulo Filter para evitar las noticias que contengan en su título el término diseño inteligente.
Hechos todos estos cambios, no tienes más que volver a guardar el diseño y ejecutar la Pipe para comprobar el resultado.
Además de módulos para recuperar contenidos de distintas fuentes y para filtrar dichas entradas, Yahoo! Pipes cuenta con muchos otros como podrás ver en el panel izquierdo del diseñador.
Los componentes del grupo User inputs permiten solicitar por teclado, antes de iniciar la recuperación de contenidos, la introducción de un número, un texto, una fecha o un URL, datos que pueden ser utilizados a continuación para, por ejemplo, componer un URL de búsqueda mediante el módulo URLBuilder. De esta forma la Pipe no genera siempre el mismo resultado, sino que éste dependerá de los datos introducidos por el usuario.
El módulo String Concatenate, en el grupo String, facilita la concatenación de cadenas, mientras que Date Formatter se encarga de convertir fechas en datos textuales.
El equipo de Yahoo! Pipes sigue trabajando en el desarrollo de otros módulos, de hecho el producto actualmente (en el momento en que se escribió este artículo) se encuentra en fase de beta. Recientemente se ha añadido el módulo Regex para la evaluación de expresiones regulares. Posiblemente cuando hagas tus primeros diseños con Yahoo! Pipes ya existan módulos adicionales a los mencionados en este artículo.
La única vía que hay actualmente para obtener provecho del gran rendimiento que ofrece el hardware, tanto los microprocesadores multi-core (CPU) como las GPU con sus cientos de núcleos de procesamiento, pasa por un rediseño del software a fin de afrontar explícitamente el paralelismo. En la entrada Programación y paralelismo (threads, GPGPU, MPI), que escribí hace un año, describía las diferentes opciones a disposición de los desarrolladores: threads, MPI, CUDA, OpenCL, etc. y en Programación y paralelismo (CPU vs GPU) profundizaba en las diferencias entre paralelismo en CPU y en GPU.
Al tratar el tema del paralelismo siempre se asume que el objetivo es emplearlo en programas que serán instalados y ejecutados en un ordenador de forma nativa, ya sea a través de compiladores específicos para un hardware concreto o el uso de máquinas virtuales que se ocupan de los detalles de más bajo nivel. En cualquier caso son aplicaciones dirigidas a funcionar bajo una cierta configuración: microprocesador, GPU, sistema operativo, etc. De un tiempo a esta parte, sin embargo, la web está ganando terreno rápidamente como plataforma para la ejecución de aplicaciones superando esas especificidades, no precisando más que un navegador que se ajuste a los estándares: HTML5, CSS3 y Javascript.
El código Javascript de una aplicación web puede ejecutar código en múltiples hilos en la CPU gracias a los Web Workers pero, hasta el momento, no existía un método que permitiese aprovechar la gran potencia con la que cuentan las GPU actuales con independencia del hardware, sistema operativo o navegador que el usuario emplee para acceder a la aplicación web. Por suerte es una situación que, todo parece indicar, cambiará en un futuro reciente gracias a
WebCL es a las aplicaciones web lo que OpenCL a las aplicaciones nativas: una capa de abstracción que permite ejecutar código en paralelo tanto en CPU como en GPU, sin importar el fabricante del hardware ni el sistema operativo empleado. Sobre OpenCL ya escribí en Programación y paralelismo (CPU vs GPU) y en Python + OpenCL = PyOpenCL. Es un estándar regido por el Khronos Group y que siguen múltiples fabricantes de hardware, entre ellos AMD/ATI, nVidia e Intel. En realidad WebCL es, fundamentalmente, un enlace o binding para poder acceder a OpenCL desde Javascript.
WebCL es un estándar en desarrollo y ningún navegador lo incluye de serie actualmente. Para poder probarlo es necesario instalar un complemento en el navegador y, por el momento y hasta donde sé, únicamente hay dos disponibles: un prototipo de Samsung para Webkit que puede utilizarse en Safari sobre MacOS X (10.6 ó 10.7) y otro de Nokia para Firefox 6 disponible para Windows y Linux (en versiones de 32 bits). Una vez instalado el complemento es posible crear desde Javascript un objeto WebCLComputeContext (en la implementación de Samsung) y usarlo para obtener información sobre el hardware disponible, preparar el código a ejecutar paralelamente y enviarlo a la CPU/GPU.
WebCL está dando sus primeros pasos. El grupo de trabajo encargado de este estándar dentro del Khronos Groups fue creado el pasado mes de mayo y, en principio, su objetivo es facilitar una guía de implementación para fabricantes conservando la esencia de OpenCL y poniendo especial énfasis en el tema de la seguridad, ya que el código se ejecutaría en el ordenador de los usuarios al acceder a una aplicación desde su navegador, sin necesidad de instalar ni ejecutar explícitamente un programa externo. En la presentación de más abajo, realizada por el Khronos Group, se ofrecen algunos ejemplos y enlaces a vídeos demostrativos del uso de WebCL y su integración con WebGL.
Publicado el 28/9/2011
Durante nuestra actividad cotidiana, a lo largo de la vida pero también en lapsos de tiempo reducido como puede ser un día o incluso pocos segundos, tomamos infinidad de decisiones que exigen la evaluación de situaciones de diversa complejidad. Aunque de manera inconsciente, no nos paramos a pensar en cómo lo hacemos, esa evaluación implica la valoración de múltiples variables, cuyo estado (valor) en conjunto nos lleva a inclinarnos por una acción u otra.
En la mayoría de las ocasiones, por no decir siempre, es más importante el hecho de que la decisión se tome a tiempo: lo antes posible, que de manera lo más exacta posible. Si la ejecución de una acción se demora en exceso es posible que cuando se tome ya no resulte útil, por tardía. Un claro ejemplo lo encontramos al pensar en cómo frenábamos nuestro automóvil al detectar la presencia de un peatón: es obvio que lo importante es frenar a tiempo, más que de manera absolutamente precisa, si no queremos que haya un siniestro. Otro ejemplo similar es el del péndulo invertido (vídeo).
Pienso que ese requerimiento de actuar rápido, que resultaba imprescindible para la supervivencia hace miles de años y que hemos ido desarrollando durante nuestra evolución y adaptando a las necesidades de cada momento, justifican en gran parte el funcionamiento de nuestra mente y, en consecuencia, la manera en que nos enfrentamos a las situaciones y decidimos. Es un método suficientemente probado, sabemos que funciona porque de lo contrario posiblemente no estaríamos aquí, así que ¿por qué no utilizarlo para automatizar la toma de decisiones y otros procesos en un ordenador? Ése es precisamente el objetivo de la teoría de conjuntos difusos y la lógica difusa.
Es habitual que al hablar no seamos excesivamente precisos en los términos que utilizamos y que, en muchos casos, utilicemos una cierta palabra asumiendo que representa el concepto que deseamos transmitir por ser sinónima (en mayor o menor grado) de la que seria correcta. La imprecisión, por tanto, está presente incluso en la forma que tenemos de hablar y por extensión en la de pensar (según diferentes estudios incluso cuando pensamos en silencio es imposible hacerlo sin utilizar la lengua materna, usando palabras y oraciones).
Para situarse correctamente es importante no confundir la imprecisión con la incertidumbre, ni tampoco con la indeterminación, términos éstos que, en una conversación, podrían pasar por sinónimos sin serlo en realidad.
La RAE define incertidumbre como la falta de certidumbre, ésta como sinónimo de certeza y ésta, a su vez, como el conocimiento seguro y claro de algo. Tener incertidumbre, por tanto, es no tener seguro ni claro el conocimiento sobre algo, por regla general algún evento. Obviamente la incertidumbre desaparece por completo una vez que dicho evento ha tenido lugar.
Análogamente la definición de imprecisión nos lleva a la falta de precisión, expresada en la tercera de las acepciones como la concisión y exactitud rigurosa en el lenguaje. En consecuencia al ser imprecisos usamos un lenguaje no conciso y cuya exactitud no es rigurosa, lo cual se ajusta bastante bien a la forma de expresarnos habitualmente: ese coche es bastante rápido, sin especificar su velocidad; mi compañero es muy alto, sin concretar la estatura, etc.
Un proceso de búsqueda similar para la palabra indeterminación nos lleva a concluir que es la imposibilidad de distinguir, discernir o fijar los términos de algo, por lo que podría decirse que la indeterminación se obtiene de la siguiente ecuación: indeterminación = incertidumbre + imprecisión.
Cuando algo es tan impreciso como para no poder ser distinguido de otros similares y, además, no somos capaces de aportar conocimiento seguro sobre él nos encontramos ante una indeterminación. El tratamiento de la indeterminación es un tema que queda fuera del ámbito de este artículo, lo que me interesaba era señalar el hecho de que no es sinónimo en ningún caso del término imprecisión.
Distinguir claramente entre estos términos es importante porque la forma de actuar del ser humano, y los métodos derivados de ella, son específicos según se trate de un imprecisión, incertidumbre o una combinación de ambas.
¿Cómo se enfrenta una persona a una situación cualquiera en su vida cotidiana con independencia de cuál sea su preparación o conocimiento previo sobre la misma? Asumimos que para ello tenemos el sentido común, una suerte de método innato en cuyo funcionamiento nunca nos paramos a pensar. ¿Cómo abordamos, por ejemplo, la necesidad de cruzar andando una vía en una ciudad?
Si la vía es una calle estrecha y larga, sabemos que normalmente nos dará tiempo a cruzarla si no vemos ningún vehículo en uno de los extremos (será de un único sentido). Si a pesar de ser estrecha es corta (de poca longitud), hemos de tener en cuenta la probabilidad de que un vehículo aparezca de repente por algún lado. La situación se complica si la vía es ancha y, aparte de permitir la circulación en dos o más carriles, da facilidad a los conductores para ir a mayor velocidad. Es necesario, por tanto, tener en cuenta los vehículos que se desplazan en cada sentido, la velocidad a la que lo hacen y nuestra propia agilidad para cruzar esa vía.
Analizando el problema soy capaz de identificar al menos las siguientes variables:
De la evaluación de éstas surgirá la decisión de en qué momento cruzar y cómo hacerlo (con más o menos celeridad).
Comienzo por la cuarta variable de las antes mencionadas: posibilidad de que otros vehículos entren en la vía y, en consecuencia, debamos tenerlos en cuenta a la hora de cruzarla. ¿Cómo se evalúa esa posibilidad? En ella influirá la longitud de la vía: si es muy larga y estamos en la parte central nos preocupará poco que entren vehículos por los extremos; la existencia de intersecciones con otras calles y también la de garajes.
Salvo que seamos adivinos o capaces de ver el futuro, esta variable lo que hace es agregar incertidumbre a la situación. ¿Cómo la tratamos para poder decidir? Echando mano de las probabilidades: el número de garajes, intersecciones con otras vías e incluso la densidad del tráfico (según la hora que sea) influyen en la probabilidad de que otros vehículos entren en la vía.
Aunque en un documento como éste, en el que se realiza un análisis detallado de la situación, podríamos dar valores a las variables y, sirviéndonos de la teoría de probabilidades, saber aproximadamente qué posibilidad hay de que ese evento suceda, en la situación real esto es imposible. En términos generales a las personas no se nos da bien el cálculo de probabilidades, por ello nos empeñamos en jugar a la lotería y nos preocupa más viajar en avión que cruzar la calle. En el primer caso la posibilidad de ganar es ínfima y en el segundo la de que tengamos un accidente es mucho mayor al cruzar la calle que en el avión.
La incertidumbre ante un evento potencial, por tanto, se evalúa como la probabilidad a priori de que se dé y tenemos herramientas para tratarla: el cálculo de probabilidades. Esa incertidumbre desaparece en el momento en que el evento concluye: nuestra incertidumbre ante el lanzamiento de una moneda nos dice que hay un 0.5 de probabilidad para cada resultado, pero una vez lanzada la probabilidad sera 1 para el resultado obtenido y 0 para el opuesto.
Solamente una de las cuatro variables antes citadas aporta incertidumbre a la situación, mientras que las otras tres pueden ser establecidas con completa certeza: el ancho de la vía será un número concreto de metros, centímetros, milímetros, etc.; la velocidad de los vehículos se puede medir en m/s y también podemos medir el tiempo que tardamos en cruzar la calle.
No obstante ningún peatón conoce esas medidas de manera exacta (no llevamos una cinta métrica para saber el ancho de la vía y un radar para conocer la velocidad de los vehículos) sino que las estima, por lo que aportan imprecisión a la situación.
En realidad si nos diesen esos datos con absoluta precisión no nos ayudarían en nada para tomar nuestra decisión de si debemos cruzar o no. ¿De qué nos sirven los centímetros y milímetros de ancho de la vía o los m/s exactos de velocidad de cada vehículo? Es suficiente con saber que la vía es muy estrecha, estrecha, normal, ancha o muy ancha y que los vehículos se acercan despacio, a velocidad normal o rápidamente. Como es fácil apreciar, éstas son etiquetas lingüísticas que asocian un valor impreciso (difuso) pero útil a cada variable.
Por lo tanto en este contexto hay que entender la imprecisión no como la existencia de ambigüedad o generalidad, sino como la ocultación de detalles innecesarios en una situación en la que el detalle excesivo en la información dificulta la operación en lugar de facilitarla. Es esta reducción del nivel de detalle, adecuándolo a la necesidad de la situación, lo que hace de la imprecisión una herramienta robusta en la toma de decisiones, una fortaleza del lenguaje humano que le permite hacer frente a sucesos muy variopintos que encuentra en su entorno.
Se indicaba antes que para el tratamiento de la incertidumbre se ha desarrollado una teoría sólida y aceptada de manera general: la teoría de probabilidades. Ésta es fácilmente trasladable a un ordenador y permite automatizar, mediante herramientas como las redes bayesianas, la toma de decisiones para ciertos tipos de problemas.
Sería deseable, por tanto, contar con una teoría análoga que nos permitiese operar cuando lo que se tiene es imprecisión en lugar de incertidumbre. Frente a la imprecisión la teoría de probabilidades resulta totalmente inútil. En realidad la matemática tradicional en su conjunto no servirá de demasiado y, por ello, se hace necesaria alguna herramienta más específica.
En palabras de Bertrand Rusell "toda la lógica tradicional asume el empleo de símbolos precisos", por lo que ya de entrada descarta por completo el uso de la imprecisión. Sin embargo ésta está presente en la vida real, como bien resumió Einstein en su famosa frase "Cuando las leyes de la matemática se refieren a la realidad no son ciertas y cuando son ciertas no se refieren a la realidad".
Según se ha visto, la imprecisión es necesaria cuando se desea aportar información útil y relevante sobre algún problema o situación compleja, ante la cual el uso de abundancia de detalles dificultarían la comprensión global. Podría decirse que cuanto mayor sea el nivel de detalle mejor conoceremos los componentes del problema, pero será menos relevante para comprender el todo.
Ya en la década de los 30 Max Black, citando la incertidumbre en la geometría de Platón, habla de conjuntos vagos y argumenta que los objetos con los que se trata en distintas teorías, como la geometría perfecta, los planetas como puntos de la astronomía o los gases perfectos de la termodinámica, nada tienen que ver con los objetos de la vida real. Se precisa una lógica que trate de la experiencia, más que de la teoría, tratando con objetos que están lejos de la perfección matemática.
Black define una proposición vaga como aquella en la que no están nítidamente definidos sus posibles estados respecto a la inclusión o exclusión, ya que éstos dependen en cierta medida de la interpretación que cada individuo haga de ellos.
Un ejemplo de este tipo de proposiciones podría ser "ser una persona mayor". Para mi hijo una persona mayor es alguien que tiene la edad de su padre o más, pero para mi madre yo no estaría incluido en el grupo de personas mayores porque soy mucho más joven que ella. Ante un problema así la lógica binaria clásica no es aplicable y, por tanto, hay que buscar una lógica alternativa.
A partir de este tipo de proposición Black habla del nivel de pertenencia en que los objetos son miembros de un conjunto, usando diferentes gradaciones y sentando las bases para una teoría general sobre la imprecisión (vagueness).
Las aportaciones de Black no fueron las únicas en ocuparse de la imprecisión, pero todo parece indicar que fueron la base sobre la que se asentó Zadeh para crear la teoría más aceptada en este campo: la de los conjuntos y la lógica difusa.
Es en la década de los 60, con la publicación de Lotfi Zadeh titulada Fuzzy sets, cuando comienza verdaderamente a desarrollarse una teoría útil para el tratamiento de la imprecisión. De hecho Zadeh se ha dedicado en gran parte durante las últimas cuatro décadas a extender las ideas recogidas en dicha publicación, desarrollando la teoría de conjuntos difusos, la lógica difusa y sus aplicaciones.
Aparte de los conjuntos vagos de Black antes mencionados, Zadeh se apoya en la lógica multivalorada de Lukaszewicz para dar a luz a los conjuntos difusos y la lógica difusa que, inicialmente, no tienen una buen acogida en la comunidad científica en gran medida por el sentido peyorativo asociado a la palabra difuso. Otro de los pilares es el principio de incompatibilidad de Pierre Duhem, que Zadeh redefine de la siguiente manera: "en la medida en que se incrementa la complejidad de un sistema se reduce proporcionalmente nuestra capacidad para explicar su funcionamiento de una manera precisa y que resulte relevante, hasta llegar a un límite a partir del cual precisión y relevancia se convierten en características prácticamente excluyentes".
El principal mérito del trabajo de Zadeh es que evidencia la posibilidad de usar las matemáticas para crear un vínculo entre el lenguaje humano y la inteligencia subyacente que conduce nuestra forma de actuar, tomando como base la lógica matemática clásica para crear una nueva capaz de operar con la imprecisión de manera sistemática, análoga a como ya se venía tratando la incertidumbre.
Los distintos trabajos de Zadeh, principalmente los publicados en las décadas de los 70, 80 y 90, introducen las herramientas principales de esta nueva teoría: los conjuntos difusos y funciones de pertenencia, las relaciones difusas, las sentencias cuantificadas, los números difusos, la lógica difusa, la extracción de reglas difusas, etc.
Pienso que la idea fundamental de toda la teoría es el hecho de definir cómo se opera sobre variables sin necesidad de cuantificarlas de manera exacta, empleando las variables lingüísticas que se ajustan mucho mejor al pensamiento humano. Para ello ha sido necesario inventar nuevos operadores, como las t-normas y t-conormas o los α-cortes, la proyección y extensión cilíndrica que permiten analizar las relaciones, etc.
Las etiquetas lingüísticas actúan como las distintas gradaciones de una variable difusa y pueden tener diferente granularidad. Es importante el hecho de que se preserve la idea de continuidad: teóricamente una variable puede tomar infinitos valores distintos, aunque por regla general se representen con 3, 5 ó 7 etiquetas. Es la continuidad precisamente la que posibilita que una pequeña diferencia entre una cierta propiedad de dos objetos no los haga distintos: dos personas con estatura de 1,90 y 1,95 se considerarán altas, a pesar de la variación de 5cm entre una y otra.
Personalmente encuentro una cierta relación entre esa continuidad o suavidad en la transición entre las etiquetas de una variable difusa y el método de inducción que empleamos con mucha frecuencia: si consideramos que una estatura N es alta, también serán altas las estaturas N-1 y N+1. Lo que cambia es la medida en que se pertenece a ese grupo.
A partir de esta teoría se han obtenido aplicaciones prácticas concretas, de las cuales quizá el mayor exponente sean los controladores difusos. La base de éstos es, en principio, bastante sencilla: la propia descripción imprecisa de un proceso por parte de una persona se convierte en un manual que permite controlarlo. Con un conjunto reducido de reglas pueden controlarse procesos aparentemente complejos y es un método que se emplea actualmente en multitud de electrodomésticos.
Con el inicio del nuevo siglo Zadeh dio un nuevo giro a sus investigaciones y propuso la idea del CW (Computing with Words) que, según sus propias palabras, permitirá abrir una nueva vía en la evolución de la lógica difusa y sus aplicaciones.
Si bien la teoría de conjuntos difusos y lógica difusa de Zadeh es la más aceptada en la actualidad, no es la única y existen varias teorías más sobre la imprecisión. Una de ellas, bastante desarrollada, se denomina AST: Alternative Set Theory. Su base es que la incertidumbre surge por el fenómeno de la infinitud al tratar con grandes variedades de estados posibles, argumentando que puede demostrarse que los números muy grandes, pero finitos, se comportan como los infinitos desde la perspectiva de la mentalidad humana. La infinitud es una cualidad dependiente del contexto.
El pensamiento humano es impreciso por naturaleza, es el principio que le permite ajustar el nivel de detalle que necesita en cada momento para poder dar respuesta a todos los problemas a los que ha de enfrentarse a lo largo de su vida. En contraposición, en el cálculo matemático y la lógica clásica es precisamente la precisión el pilar fundamental. Anecdóticamente resulta bastante más sencillo formular operaciones sobre datos precisos que con datos imprecisos. Por ello teorías como las de la probabilidad llevan asentadas desde hace más de dos siglos y, por el contrario, hasta hace pocas décadas se carecía de una teoría que permitiese tratar de forma sistemática la imprecisión.
Las teorías sobre la imprecisión han tratado de dar respuesta a la necesidad de contar con herramientas que permitan de alguna manera modelar los problemas como lo hace la mente humana, entrando en campos como la psicología, neurología, biología y computación. Todo este esfuerzo se explica por el importante papel que en ingeniería y ciencias de la computación tiene la capacidad para tratar con la imprecisión.
Se puede ampliar este artículo con la bibliografía referenciada a continuación si se quiere obtener una idea global sobre multitud de aspectos que explican porqué es interesante aprender sobre conjuntos difusos, lógica difusa, reglas difusas, etc., ya que son las herramientas que permitirán simular/emular en un programa de ordenador el comportamiento de uno mismo y, por tanto, abre las puertas a otras maneras de resolver los problemas, seguramente más coherentes con el pensamiento humano.
A medida que se han ido incorporando en la tarjeta de vídeo funciones más avanzadas, influidas por la necesidad de satisfacer requisitos más exigentes en la generación de gráficos y también las nuevas API de programación (OpenGL y DirectX), ha surgido un nuevo concepto: el de GPU (Graphics Processor Unit), como analogía de las CPU (Central Processing Unit) o microprocesadores clásicos. En realidad es algo que lleva casi dos décadas evolucionando, aunque para los programadores ajenos al campo de los vídeojuegos pueda considerarse algo nuevo.
Si bien la denominación GPU hace referencia a una arquitectura especializada, dirigida específicamente al tratamiento gráfico, cada vez es mayor el número de aplicaciones que aprovechan la potencia de estos circuitos integrados para otro tipo de propósitos. Es aquí, precisamente, donde cobran protagonismo soluciones como Cg, ATI Stream, OpenCL y CUDA, infraestructuras compuestas de bibliotecas, compiladores y lenguajes que dan a luz a una nueva filosofía de desarrollo: GPGPU (General Purpose computing on Graphics Processing Units), la computación de propósito general usando GPUs en lugar de CPUs.
¿Cuál es la razón de que los programadores se interesen en desarrollar aplicaciones que se ejecuten en una GPU? La respuesta surge por sí sola simplemente aportando algunos datos: las actuales CPU cuentan con cuatro, seis u ocho núcleos y son capaces de ejecutar hasta doce hilos de manera simultánea (dos por núcleo en algunos casos), las GPU más avanzadas disponen de hasta 1024 núcleos de procesamiento y tienen capacidad para ejecutar hasta 128 hilos por procesador, lo que ofrece un total de hilos muy superior. Sistemas compuestos únicamente de ocho tarjetas de vídeo de este tipo están superando, en cuanto a rendimiento se refiere, a clústeres de ordenadores como Blue Gene, formados por 512 nodos con CPUs clásicas.
Para aprovechar la potencia de las GPU es necesario contar con herramientas de desarrollo adecuadas, capaces de explotar el alto nivel de paralelismo que ofrecen estos dispositivos. Hasta no hace mucho dichas herramientas eran bastante primitivas, ya que su objetivo era facilitar exclusivamente la programación de shaders que (véase el Curso de shaders en el margen derecho) son pequeños bloques de código que aplican un cierto procesamiento a los vértices de la geometría de una escena y los fragmentos resultantes de la rasterización. Ese código se ejecuta paralelamente en cada núcleo, lo cual permite aplicar un cierto algoritmo masivamente a miles o millones de vértices y píxeles.
Estos bloques de código tienen una longitud generalmente muy limitada y se programan en una suerte de lenguaje ensamblador a medida, por lo que difícilmente pueden aplicarse más que a la función para la que están pensados desde un principio. Existen diferentes versiones, denominadas Shader Models, que han ido evolucionando en paralelo a Microsoft DirectX y OpenGL y que tanto ATI como nVidia han ido implementando en su hardware. Al desarrollar una aplicación gráfica se utiliza una API, como las citadas DirectX u OpenGL, para escribir el código que se ejecutará en la CPU, usando el ensamblador del shader model correspondiente para escribir el código a ejecutar en la GPU. Tanto el tipo de operaciones que puede llevar a cabo ese código como la memoria a la que tiene acceso están limitados.
El desarrollo de Cg por parte de nVidia, hace prácticamente una década, fue un primer avance al facilitar la codificación de funciones a ejecutar en la GPU. En lugar de escribir el código en ensamblador se usa un lenguaje de más alto nivel, similar al C. Una función como la mostrada en el siguiente fragmento se ejecutaría una vez para cada vértice, pero no de manera secuencial sino paralelamente.
A diferencia de CUDA, no obstante, Cg se dirige específicamente a la generación de gráficos. A medida que el número de núcleos de proceso en una GPU se fue incrementando, y ganando en rendimiento al poder operar con datos en coma flotante, se hizo cada vez más patente la necesidad de aprovechar esa potencia bruta de cálculo para propósitos alternativos, aparte de la evidente aplicación en videojuegos de última generación. Solamente se precisaban herramientas de trabajo de corte más general, con un espectro de aplicación más amplio.
La mayoría de los lenguajes de programación no cuentan con estructuras nativas que faciliten la paralelización de procesos, entendiendo como tales partes de un algoritmo que pueden ser ejecutados de manera simultánea y no como lo que se entiende por procesos en el contexto de un sistema operativo.
Es cierto que existen API y bibliotecas de funciones que facilitan, hasta cierto punto, la programación paralela, pero prácticamente ninguna de ellas está pensada para ejecutar el código explotando una GPU. En la mayoría de los casos lo único que hacen es iniciar varios hilos de ejecución dejando en manos del sistema operativo el reparto de tiempo de proceso entre las unidades con que cuente la CPU. Para trasladar la aplicación a otro tipo de procesador, así como para ampliar o reducir el número de hilos en ejecución, es corriente tener que alterar, o incluso rescribir por completo, el código fuente.
La solución que ofrece CUDA (Compute Unified Device Architecture) es mucho más flexible y potente y, además, se basa en estándares existentes. Los programas se escriben en lenguaje C, no en el ensamblador de un cierto procesador o en un lenguaje especializado como es el caso de Cg. Esto facilita el acceso a un grupo mucho mayor de programadores.
Al desarrollar una aplicación CUDA el programador escribe su código como si fuese a ejecutarse en un único hilo, sin preocuparse de crear y lanzar threads, controlar la sincronización, etc. Ese código será ejecutado posteriormente en un número arbitrario de hilos, asignado cada uno de ellos a un núcleo de proceso, de manera totalmente transparente para el programador. Éste no tendrá que modificar el código fuente, ni siquiera recompilarlo, dependiendo de la arquitectura del hardware donde vaya a ejecutarse.
Incluso existe la posibilidad de recompilar el código fuente, dirigido originalmente a ejecutarse sobre una GPU, para que funcione sobre una CPU clásica, asociando los hilos CUDA a hilos de CPU en lugar de a núcleos de ejecución de GPU. Obviamente el rendimiento será muy inferior ya que el paralelismo al nivel de CPU no es, actualmente, tan masivo como en una GPU.
Los objetivos planteados en el desarrollo de CUDA han dado como fruto un conjunto de tres componentes, disponibles gratuitamente en Developer Zone de nVidia para versiones de 32 y 64 bits de Windows XP, Windows Vista, Windows 7, múltiples distribuciones de GNU/Linux y Mac OS X.
El controlador CUDA es el componente básico, ya que es el encargado de facilitar la ejecución de los programas y la comunicación entre CPU y GPU. Este controlador se aplica a prácticamente toda la gama GeForce 8XX, 9XX y GTX 2XX y posteriores, así como a la línea de adaptadores Quadro y los procesadores Tesla. En cualquier caso se requiere una cantidad mínima de 256 MB de memoria gráfica para poder funcionar, por lo que en adaptadores con menos memoria no es posible aprovechar CUDA.
Instalado el controlador, el siguiente componente fundamental para el desarrollo de aplicaciones es el toolkit CUDA, compuesto a su vez de un compilador de C llamado nvcc, un depurador específico para GPU, un perfilador de código y una serie de bibliotecas con funciones de utilidad ya predefinidas, entre ellas la implementación de la Transformada rápida de Fourier (FFT) y unas subrutinas básicas de álgebra lineal (BLAS). También en la misma web se encuentran múltiples documentos de introducción a la programación de GPUs con CUDA, manuales de referencia, etc.
El tercer componente de interés es el CUDA Developer SDK, un paquete formado básicamente por código de ejemplo y documentación. Se ofrece más de medio centenar de proyectos en los que se muestra cómo integrar CUDA con DirectX y OpenGL, cómo paralelizar la ejecución de un algoritmo y cómo utilizar las bibliotecas FFT y BLAS para realizar diversos trabajos: generación de un histograma, aplicación de convolución a una señal, operaciones con matrices, etc.
Conjuntamente estos tres componentes ponen al alcance del programador todo lo que necesita para aprender a programar una GPU con CUDA y comenzar a desarrollar sus propias soluciones, apoyándose en código probado como el de los ejemplos facilitados o el de las bibliotecas FFT y BLAS.
El código de un programa escrito para CUDA siempre estará compuesto de dos partes: una cuya ejecución quedará en manos de la CPU y otra que se ejecutará en la GPU. Al código de la primera parte se le denomina código para el host y al de la segunda código para el dispositivo.
Al ser procesado por el compilador nvcc, el programa generará por una parte código objeto para la GPU y por otra código fuente u objeto para la CPU. El código objeto específico para la GPU se denomina cubin. El código fuente para la CPU será procesado por un compilador de C/C++ corriente, enlazando el código cubin como si de un recurso se tratase.
La finalidad del código host es inicializar la aplicación, transfiriendo el código cubin a la GPU, reservando la memoria necesaria en el dispositivo y llevando a la GPU los datos de partida con los que se va a trabajar. Esta parte del código puede escribirse en C o en C++, lo cual permite aprovechar el paradigma de orientación a objetos si se quiere.
El código a ejecutar en el dispositivo debe seguir estrictamente la sintaxis de C, contemplándose algunas extensiones de C++. Normalmente se estructurará en funciones llamadas kernels, cuyas sentencias se ejecutarán en paralelo según la configuración hardware del dispositivo final en el que se ponga en funcionamiento la aplicación.
Lo que hace el entorno de ejecución de CUDA, a grandes rasgos, es aprovechar el conocido como paralelismo de datos o SIMD (Simple Instruction Multiple Data), consistente en dividir la información de entrada, por ejemplo una gran matriz de valores, en tantos bloques como núcleos de procesamiento existan en la GPU. Cada núcleo ejecuta el mismo código, pero recibe unos parámetros distintivos que le permiten saber la parte de los datos sobre los que ha de trabajar.
El listado siguiente corresponde a una función kernel muy sencilla, cuyo objetivo es hallar el producto escalar de una matriz por una constante. La función solamente opera sobre un elemento de la matriz, el que le indica la variable threadIdx.x que identifica el hilo en que está ejecutándose el código. Esta función se ejecutaría paralelamente en todos los núcleos de la GPU, por lo que en un ciclo se obtendría el producto de una gran porción de la matriz o incluso de ésta completa, dependiendo de su tamaño y el número de núcleos disponibles.
En una CPU moderna, como los Athlon Phenom o Core i7, es posible dividir los datos de entrada en cuatro o seis partes pero sin ninguna garantía de que se procesarán en paralelo, salvo que se programe explícitamente el reparto trabajando a bajo nivel. En una GPU y usando CUDA, por el contrario, esos datos se dividirán en bloques mucho más pequeños, al existir 240, 512, 1024 o más núcleos de procesamiento, garantizándose la ejecución en paralelo si necesidad de recurrir a la programación en ensamblador.
El pasado día 16 de marzo, como ya anuncié por aquí, se inauguró después de muchos meses de trabajo la exposición El pasado de la computación personal - Historia de la retroinformática (vídeo). Ésta echará el cierre el próximo día 26 de abril y, aunque todavía quedan algunos días para que aquellos que quieran visitarla puedan acercarse hasta el Edificio Zabaleta de la Universidad de Jaén, el mes ya transcurrido es suficiente para hacer una breve recapitulación de cuáles han sido los resultados.
La exposición se inauguró con una breve charla (grabación) sobre la historia de la retroinformática y el papel que jugó en la evolución de la informática empresarial (de principios de los 70) hacia la informática personal, haciendo especial hincapié en la influencia que tuvo y que ha hecho posible que hoy tengamos los dispositivos que tenemos.
También en el acto de inauguración se hizo público el libro El pasado de la computación personal - Historia de la retroinformática, tanto en papel como en su versión digital. La versión impresa ha estado a disposición de los visitantes de la exposición y la demanda que ha tenido nos sorprendió gratamente. Tanto el contenido, abundante en fotografías de microordenadores y una historia repleta de anécdotas, como la calidad de la impresión, a todo color, ha hecho que el libro se convierta en objeto de deseo para muchos y que incluso aparezca como premio en algunos concursos. Para aquellos que no han podido conseguirlo, la versión en PDF estará siempre a disposición pública sin límite de tiempo ni restricciones en cuanto a la realización de copias. También puede leerse, sin necesidad de descargarlo, desde el sitio del Secretariado de Actividades Culturales de la UJA. Un clic sobre la portada lo mostrará a pantalla completa.
El mismo día de la inauguración atendimos a distintos medios, principalmente locales, tanto de prensa escrita (Diario Jaén, Diario Ideal, El Mundo), como radio y TV (Onda Jaén, Canal Sur y algún otro que no recuerdo). Personalmente no he oído/visto las entrevistas en radio y TV ni tengo referencias sobre cómo acceder a ellas, pero sí a las publicadas en diversos medios digitales, entre ellos varios blogs dedicados específicamente al tema retroinformático. La siguiente es una lista no exhaustiva de las mismas:
Además de éstas han aparecido infinidad de referencias breves a la exposición en la web, especialmente en sitios relacionados con su temática pero también en otros más generales como Barrapunto.es. Asimismo se han publicado entrevistas únicamente en papel, por ejemplo en el suplemento Campus del Diario Jaén.
Por lo que nos cuenta el personal que está a pie de la exposición, cuidando de que todo esté perfecto cada día, la afluencia de visitantes ha sido muy grande. A las del público en general, principalmente estudiantes y personal de la Universidad de Jaén, hay que sumar la de grupos de estudiantes de IES y de ciertas titulaciones de la propia UJA, así como muchos aficionados (realmente algunos son expertos) a la retroinformática que no han dejado pasar la oportunidad de recordar sus inicios en la informática.
En pocos días, el próximo miércoles 27 de abril, el equipo que ha hecho posible esta exposición acudirá a la misma para proceder a su desmontaje, dejando paso a una nueva. Cuando todo vuelva a su sitio llegará también el momento de tomarse un pequeño respiro, un descanso merecido después de tanto tiempo de trabajo antes y durante la exposición. Ésta surgió de una idea previa, el museo virtual ReturnOK, que se convirtió en un Proyecto de Innovación Docente premiado en su día por la UJA en competencia con otros, un proyecto que participó en las I Jornadas de Innovación Docente Universitaria que tuvieron lugar en la Universidad de Córdoba en noviembre de 2009 y que también estuvo presente en el V Congreso Internacional de Conservación del Patrimonio e Historia de la Ingeniería en 2010.
En cuanto recobremos fuerzas volveremos con más ideas, más proyectos y seguiremos trabajando para que la historia de la microinformática esté presente en ámbitos en los que, normalmente, es desconocida por completo.
Ya está disponible el libro asociado a la exposición que anunciaba hace un par de días y que quedará inaugurada en la Universidad de Jaén el 16 de marzo de 2011. En él se recoge la historia de la microinformática en España, con detalles de los fabricantes que tuvieron mayor presencia en este país, las máquinas que ofrecían,información sobre software, unidades de almacenamiento, bibliografía, etc. Licencia Creative Commons descargarlo gratuitamente (PDF).
La inauguración irá precedida de una conferencia sobre el mismo tema, a las 12:30 del día 16, en la Sala de Juntas del Edificio Zabaleta. Si no puedes asistir físicamente, también puedes seguirla mediante videoconferencia.
El próximo día 16 se inaugurará en la sala de exposiciones del Edificio Zabaleta de la Universidad de Jaén la exposición El pasado de la computación personal: HISTORIA DE LA MICROINFORMÁTICA, quedando abierta hasta el día 26 de abril.
La inauguración estará precedida de una conferencia, a las 12:30 en la sala de juntas del mismo edificio, en la que se expondrá la importancia que la microinformática tuvo en los 70 y 80 y cómo influyó en la evolución de la informática personal hasta llegar a la actualidad.
En la exposición los visitantes podrán ver una selección de microordenadores de mi colección, parte de los cuales he descrito en las entradas de meses previos de la sección El retrosótano. Las máquinas presentes serán:
Además también se expondrán diferentes unidades de almacenamiento: disqueteras de 8, 5.25 y 3.5 pulgadas, lectores de cinta, etc., y sus correspondientes soportes, así como libros y revistas de la época.
Esta exposición llevará asociada la publicación de un libro, por parte del servicio editorial de la Universidad de Jaén, recogiendo la historia de muchas de estas máquinas y de la propia evolución de la microinformática. A petición mía, la licencia de dicho libro será Creative Commons y estará disponible para descarga libre. En cuanto tenga el enlace lo pondré por aquí.
Finalmente, decir que la conferencia será retransmitida en directo por videoconferencia para aquellos que quieran seguirla y no puedan asistir de manera presencial. En su momento facilitaré el enlace a a través de Twitter y si me es posible lo pondré también por aquí.
El patrón arquitectónico MVC (Model-View-Controller) es, en la actualidad, un estándar muy asentado para el desarrollo de sistemas software que precisan interactuar con personas y que, por tanto, entre sus componentes existe una interfaz de usuario. Todo ingeniero de software conoce este patrón y en la red es posible encontrar infinidad de artículos explicándolo. En esta breve entrada solamente se ofrece una visión histórica del mismo y, sobre todo, se destacan las ventajas que aporta al desarrollo de aplicaciones.
El primer documento en que se habla de la separación de los elementos de un sistema software en un modelo de ordenador, un software controlador y una vista manipulable por el usuario surge en los Xerox PARC (Palo Alto Research Center) en 1978 en The original MVC reports, mencionándose un componen adicional, llamado Editor, que forma parte de la vista.
Durante el desarrollo de una aplicación (por parte de un científico visitante que pasaba una temporada en el PARC) se hizo patente la necesidad de buscar una solución general al problema que planteaba el control de un conjunto de datos grande y complejo por parte de un usuario. El objetivo era adaptar el modelo de ordenador de esos datos al modelo mental de la persona que debía usarlos, interponiendo los componentes software apropiados para ello.
La aplicación a desarrollar era un sistema de planificación y en él se empleaban cuatro metáforas: thing, model, view y editor, extrapolación del objeto de interés para el usuario, la abstracción de ese objeto en forma de datos en un ordenador, una o más posibles representaciones de dicho objeto y la interfaz entre el usuario y esas vistas, respectivamente.
Tras un proceso de refinamiento se definió el modelo como una representación del conocimiento con el que debe trabajar el sistema, la vista como una representación visual de ese modelo y se introduce el controlador como el enlace entre el usuario y el sistema. Estas ideas se plasman en un documento publicado el 10 de diciembre de 1979 con el título Model-Views-Controllers, naciendo el acrónimo MVC.
La primera implementación de MVC como patrón arquitectónico, más allá de la aplicación puntual que le dio origen, se efectuó en el propio PARC para la librería Smalltalk-80. A partir de ese momento comenzó su popularización y se extendió su uso, con independencia de plataformas, lenguajes de programación e incluso arquitectura del sistema a desarrollar.
Es necesario partir de la base de que este patrón es aplicable exclusivamente a sistemas software en los que se precisa interacción por parte del usuario, no teniendo sentido fuera de dicho contexto.
Un mismo sistema puede contar con múltiples vistas, dependiendo por ejemplo del tipo de usuario que lo utiliza. Una aplicación bancaria, por poner un ejemplo, ofrece una vista especializada al cliente que accede a través de la Web desde su ordenador, distinta de la que obtiene el trabajador que atiende físicamente en la oficina a los clientes. El sistema es el mismo, pero las vistas obviamente no.
Además las vistas suelen evolucionar con el tiempo, adaptándose a los nuevos toolkit de los sistemas operativos, a nuevos dispositivos como los teléfonos móviles o sencillamente adaptándose a nuevas necesidades. En contraposición, el modelo interno del sistema suele mantenerse estable a lo largo del tiempo y raramente cambia una vez concluida la fase de desarrollo. Podría decirse que el modelo es la esencia invariable del sistema y es la plasmación del conocimiento que se tiene del dominio en una estructura interpretable por un ordenador.
Diseñar (y especialmente mantener) un sistema en el que unos componentes cambian dinámicamente durante la ejecución y/o a lo largo del tiempo y deben comunicarse con otros invariables representa una cierta dificultad. En este contexto el patrón MVC facilita el desacoplamiento de dichos componentes, de forma que es posible cambiar de vista con gran sencillez sin necesidad de alterar en ningún sentido el modelo.
Para que el modelo pueda permanecer inmutable a lo largo del tiempo es indispensable que esté completamente desconectado del mundo exterior, es decir, el modelo no tiene conocimiento alguno sobre la vista ni acerca del controlador. Esto se consigue principalmente mediante la aplicación de dos patrones software bien conocidos: el patrón estrategia y el patrón observador.
El patrón observador permite al modelo notificar hacia el exterior los cambios que se produzcan en el estado del sistema, pero sin conocer detalle alguno sobre el componente al que está notificando. Esto hace posible que el controlador y la vista reciban mensajes desde el modelo sin que éste cuente con un conocimiento explícito sobre aquellos.
Aunque la arquitectura MVC no lo establece explícitamente, el desacoplamiento entre el modelo y los demás componentes del sistema se incrementa si estos últimos tampoco tienen un conocimiento directo del primero, para lo cual se recurre al citado patrón estrategia. Lo que controlador y vista tienen es una interfaz de acceso al modelo, no una referencia directa a los objetos que lo componen.
Cabe preguntarse, si el modelo no tiene conocimiento de vista ni controlador y éstos no conocen directamente el modelo, ¿cómo es posible que el sistema opere como un todo? Por convención cuando el sistema se pone en marcha crea el controlador y deja en sus manos la creación del modelo y la vista o vistas que pudieran existir, estableciendo las conexiones adecuadas entre ellos.
En resumen, el patrón arquitectónico MVC favorece el diseño de sistemas software en base a componentes que tienen una alta cohesión: únicamente el modelo gestiona el estado del sistema, solamente la vista genera representaciones visuales de dicho estado etc.; y mantienen un elevado grado de desacoplamiento, haciendo posible la modificación e incluso sustitución de cualquiera de ellos sin afectar al resto. Todo ello contribuye a simplificar el diseño de aplicaciones complejas que, de otra forma, resultarían mucho más difíciles de abordar y mantener.
A continuación una selección de los twits sobre tecnología en @fcharte del pasado mes de enero:
El 27 de enero de 1948, hace hoy 63 años, IBM presentaba en la planta baja de sus oficinas en Nueva York, a la vista de todos los viandantes, el SSEC (Selective Sequence Electronic Calculator). El IBM SSEC, a pesar de la denominación de calculadora, era un ordenador electro-mecánico: en su construcción se combinaron los relés mecánicos de máquinas anteriores con las válvulas de vacío que en el futuro darían lugar a los primeros ordenadores electrónicos. La denominación ordenador se evitaba porque no estaba bien vista desde un punto de vista comercial, ya que por entonces se asumía que los ordenadores quitaban el trabajo a las personas, de ahí que se le llamase máquina de cálculo.
A pesar de no ser un ordenador electrónico, el SSEC fue el primer ordenador en funcionar con un programa almacenado, en contraposición a los ordenadores previos cuya reprogramación implicaba un recableado de la circuitería. La velocidad a que operaba el SSEC multiplicaba por 100 la del MARK I, un predecesor que comenzó a funcionar en 1944. Su capacidad de almacenamiento era de 400.000 dígitos. La combinación de velocidad, capacidad y baja tasa de errores, con solamente un fallo cada 8 horas, le hizo el ordenador ideal para cálculos complejos, llegando a utilizarse para determinar las posiciones de los planetas, de la luna y prever trayectorias de cohetes del programa espacial estadounidense.
El IBM SSEC, como puede apreciarse en las fotografías de The IBM Selective Sequence Electronic Calculator, ocupaba un espacio considerable, aproximadamente la mitad de un campo de fútbol. En dichas imágenes puede verse la consola de operador de la máquina, del tamaño de un escritorio y con cientos de indicadores luminosos ocupando todo el frontal, a modo de pantalla, y parte de un lateral.
En la biografía de John Backus, creador del lenguaje de programación FORTRAN y la notación BNF (Backus-Naur Form) que resultará familiar a todo el que haya estudiado teoría de lenguajes formales y diseño de compiladores, se indica cómo la visión desde el exterior del SSEC le llevó a entrar en las oficinas de IBM y ofrecerse para trabajar con él. La empresa le contrató y Backus pasó tres años trabajando con el SSEC, hasta que éste dejó de operar en agosto de 1952.
Según el artículo The SSEC in Historical Perspective, publicado por Charles J. Bashe en el número de octubre de 1982 de la revista Annals of the History of Computing, el IBM SSEC se convirtió en el ordenador más flexible y potente en funcionamiento en aquel momento en todo el mundo. Más interesante aún es el artículo A Large-Scale, General-Purpose Electronic Digital Calculator: The SSEC, escrito en 1948 y reproducido en el mismo número de la revista mencionada, en el que se detallan las características de la máquina, su diseño y funcionamiento, todo ello acompañado de fotografías de las unidades de cálculo, de cinta, el lector de tarjetas, etc.
Cuando se habla de software libre uno siempre tiende a pensar en el sistema operativo GNU/Linux, el servidor web Apache, la base de datos MySQL, el paquete ofirmático OpenOffice/LibreOffice o el programa para gráficos GIMP. Son quizá los máximos exponentes de un ecosistema poblado por miles y miles de aplicaciones para todo tipo de tareas: clientes web (navegadores) y de correo electrónico, herramientas de desarrollo para multitud de lenguajes, visores de infinidad de tipos de archivos, juegos, etc.
Una de las categorías quizá menos conocida sea la del software libre para profesionales y empresas, el software aburrido pensado para llevar las cuentas (contabilidad) o controlar los clientes/proveedores/productos (gestiónc comercial), para gestionar proyectos y muchas otras tareas similares. Ese software existe y la lista siguiente es una pequeña recopilación de parte del mismo:
Esta entrada es continuación de Microordenadores MSX (I) en la que se contaba el origen de la norma MSX y las características comunes de la primera generación de estos microordenadores, junto con detalles específicos de algunos modelos. En esta segunda parte se aborda el fin de la historia de los MSX, con la segunda generación: MSX2, y los bastante raros por estas latitudes MSX2+ y MSX TurboR.
La primera generación de MSX tuvo bastante éxito en ciertos países (véase la primera parte de la historia), vendiéndose varios cientos de miles de unidades en los primeros meses. Esto llevó a los fabricantes a plantearse una renovación en 1985, frente a la aparición de los primeros sistemas de 16 bits, así como a una mayor implicación por parte de algunos de ellos como fue el caso de Philips, empresa holandesa con importantes ventas en su país de origen y otros de Europa, entre ellos España.
A pesar de que se planteó la posibilidad de utilizar un microprocesador de 16 bits, para poder competir en igualdad de condiciones con el Atari ST que se había presentado en el CES de las Vegas en 1985 y el Commodore Amiga lanzado poco después el mismo año, pesó más la necesidad de conservar la compatibilidad con todo el hardware y el software existente. El MSX2 no fue una revolución, como esas máquinas respecto a los modelos precedentes de sus respectivos fabricantes, sino una evolución de la primera generación. No obstante la nueva especificación permitió a los fabricantes crear microordenadores que podían competir, hasta cierto punto, con los citados ST y Amiga e, incluso, en algunos aspectos superarlos.
El MSX2 se lanza en Japón en 1985, llegando ya en 1986 al resto del mundo, Europa incluida. Recuerdo que tuve mi primer contacto con un MSX2 en la primavera de 1986, en una presentación que Philips realizó en Granada en relación con el Plan Alhambra, un proyecto educativo de la Junta de Andalucía que tenía el objetivo de introducir los ordenadores en los colegios. En dicho evento Philips usó un VG-8235, uno de los primeros MSX2 disponibles aquí, conectado a un vídeodisco o dispositivo similar para mostrar las aplicaciones de su máquina a la educación, controlando vídeo, facilitando el acceso a enciclopedias y, como colofón, al final mostró un software aún inacabado (pero que dejó bastante impresionada a la asistencia) en la que una entrenadora digital los dirigía por una sesión de aerobic (aún faltaban bastante años para la aparición de la Wii y y similares).
A pesar de conservar el mismo microprocesador, los MSX2 incorporaban nuevos circuitos de vídeo y audio, más memoria RAM y VRAM, nuevas versiones del intérprete de BASIC y el sistema operativo MSX-DOS y casi todos los modelos integraban una unidad de disco de 3.5 pulgadas y 360KB o 720KB, según los casos. En algunos apartados, como era el caso de los gráficos, los MSX2 superaban a modelos de 16 bits como el Atari ST, al permitir el uso de hasta 256 colores de una paleta de 512 y poder generar imágenes como la de la figura inferior. Ésta forma parte de una demostración de la propia Philips durante el citado evento en Granada.
Torre de Babel - Francisco Charte Ojeda - Desde 1997 en la Web