C++/CX (I). Windows 8 y el nuevo subsistema WinRT

image

Observad con detalle la imagen de arriba. Fijaos en que está dividida en dos grandes bloques. A poco que os haya preocupado la arquitectura lógica de Windows, os daréis cuenta de que hay nueva chica en la oficina: WinRT.

Ya hablé de algo así aquí, pero en relación con la arquitectura de Apple comparada con la de Windows, y de los últimos cambios que Microsoft ha ido haciendo para adecuar su plataforma NT para que sea funcional y útil para el usuario medio, dejando un poco de lado la arquitectura tradicional.

Pues bien, parece ser que me tengo que comer mis palabras con patatas (no, no esas patatas, Z). Volviendo al gráfico anterior, WinRT es un nuevo subsistema igual que lo es Win32. Para aquellos que no tengan claro qué es, os cuento un poco la arquitectura teórica de Windows NT.

El sistema operativo cuenta con un kernel (sí, como el de Linux, pero con muchas más cosas dentro de él y mucho más dinámico), que en teoría se asienta sobre una capa HAL que abstrae a dicho núcleo de la arquitectura física. En su momento hubo HAL para ARM y para otras plataformas. En la actualidad sólo la hay para x86, tanto en versión de 32 como de 64 bits.

O eso creía tras haber hecho un somero análisis de las tripas de Windows 7. Pues bien, si Microsoft añade soporte para ARM (y recordemos que van a salir procesadores de este tipo de 64 bits), dicha capa debe ser o bien reimplementada o bien ya existía y simplemente estaba inactiva. O lo que me parece más lógico: recompilar todo el sistema operativo para que se ejecute en dicha arquitectura, cambiando lo que haya que cambiar, dado que eso de traducir cualquier otro procesador a x86, sobre todo desde un ARM, suena a fantasía animada de ayer y de hoy.

Por otro lado, Windows se mueve mediante subsistemas. Uno de ellos es Win32. Otro lo fue OS/2 y también Posix (sí, en un pasado lejano, Windows NT era capaz de ejecutar comandos de unix con las primitivas de desarrollo que tiene la parte estándar Posix de Unix). Es decir, un subsistema suministra cierta abstracción sobre el núcleo, proporcionando un API mucho más rico y potente. Y de paso lo aísla para que las aplicaciones sean incapaces de tumbarlo.

En otras palabras, Win32 se ejecuta en el anillo 3 y el núcleo en el cero, y es Win32 el que, cuando una aplicación pide algún recursos del sistema (por ejemplo un puerto serie), el que se encarga de mover la petición y de realizar tareas intermedias, evitando así que un mal uso por parte de una aplicación genere una pantalla azul.

Digamos que una aplicación en el anillo 3 jamás podrá tumbar al sistema ejecutándose en el anillo 0, o al menos esa es la teoría. A veces un parámetro mal pasado puede terminar en una caída completa, pero no es lo habitual, y cada vez menos.

Pues bien, aparte de Win32, ahora tenemos un nuevo subsistema llamado WinRT. O eso dice, al menos la teoría y así nos lo presenta Microsoft en sus gráficos y en la escasísima información de la que disponemos.

Una de mis próximas tareas es la de intentar averiguar si esto es así o no lo es. No es la primera vez que Microsoft miente descaradamente, como cuando dijo de XAML no iba a necesitar de Win32 y que desaparecían los bucles de mensajes y que se ejecutaría sobre DirectX… Hasta donde sé, todavía eso no es del todo cierto.

También nos dijo que .NET iba a ser un subsistema, y realmente se ha quedado como una capa sobre Win32…

Por lo tanto, estad atentos al blog. Además, el dibujo original de Microsoft deja mucho que desear respecto a la claridad, presentando Internet Explorer y .NET como subsistemas independientes de Win32, lo que es, a todas luces, completamente falso:

image

***

Volviendo al gráfico de arriba, podemos ver algunos detalles que creo no son del todo ciertos, pero nos dan una idea de la arquitectura del nuevo WinRT (sobre la que se basa la interfaz METRO que llevará, junto al escritorio tradicional, Windows 8).

(Una de las cosas por las que dudo que WinRT sea un subsistema completo es el hecho de que Windows 8 consuma menos memoria que el 7 y de que se pueda producir ese intercambio tan rápido entre los dos escritorios, lo que me hace pensar que, de nuevo, se trata de algo sobre Win32).

En WinRT hay dos interfaces de desarrollo principales: XAML y HTML. Es decir, podemos hacer aplicaciones clásicas basadas en el primer modelo y modernas en el segundo.

A simple vista puede parecer que en ambas se utiliza una misma variación del XML, pero no es así. En el caso de HTML/CSS nuestra aplicación no será otra cosa más que una página web ejecutándose dentro de una sesión más o menos oculta de Internet Explorer. Tendremos acceso a esas dos tecnologías (incluyendo HTML5) y JavaScript como lenguaje de desarrollo.

En el caso de XAML, estamos ante la última evolución de las interfaces de usuario dinámicas en las que la interfaz está completamente (o lo más posible) separada del código en sí, lo que permite una soltura nunca vista hasta ahora. O al menos esa es la teoría y casi os diría que la práctica.

XAML es muy potente. Demasiado, casi diría. Se trata de una especie de colección de contenedores jerárquicos que pueden actuar como tales o como elementos finales, y pueden mutar de un tipo a otro con una facilidad pasmosa. De hecho, cambiar el aspecto visual de una aplicación XAML puede llegar a ser cosa de unas pocas –muy pocas- líneas de código, con el añadido de que quien haya desarrollado con .NET y la versión anterior, está casi listo para esta nueva (que por cierto no es mi caso, pese a ver en su momento las ventajas evidentes del nuevo modelo).

Por lo tanto, los programadores de .NET que hayan abandonado Windows Forms por la nueva forma, lo tendrán bastante fácil. Los dinosaurios como yo mismo tendremos ciertas dificultades en adaptarnos… o no.

¿Recordáis C++/CLI, el C++ del .NET? Pues bien, la única pega para que dicha extensión de C++ pudiera utilizar XAML es que no se soportan las clases parciales como en C o en VB.NET. Por desgracia, eso sigue siendo así, y la interfaz clásica continua estando vedada para los programadores de C++ en .NET, quedando limitados a Windows Forms y a un IDE que no es que se muestre muy estable manejando el lenguaje…

***

Bueno, ahora, por fin, entra C++/CX. ¿Qué es? Nada más y nada menos que una nueva extensión a C++, con una sintaxis muy similar a C++/CLI pero con un propósito muy diferente: el de soportar METRO y XAML. Y no, no es .NET. Es nativo.

Supongo que Microsoft se planteó ante una disyuntiva muy pero que muy gorda: el rendimiento de .NET es suficiente para un PC, pero no lo es para una plataforma móvil como una tableta. No estoy diciendo que sea malo, estoy diciendo que eso de tener una máquina virtual consumiendo memoria y recursos, un jitter ejecutándose detrás de todo, y un post-compilador pasando MSIL a código nativo no es de recibo para un Tablet.

Delante de todos está el fracaso de Android. Por favor, absteneros fundamentalistas y otros pájaros de similar calaña: Android es un fracaso. Puede que aguante unos cuantos años, pero terminará por caer estrepitosamente, tanto por problemas técnicos (demasiado consumo de memoria, demasiada lentitud, demasiadas capas una encima de otra, demasiadas caídas) como por comerciales (demasiada fragmentación, demasiado abandono de terminales a medio hacer), etc..

Por lo tanto, para competir en igualdad de condiciones, tenemos que darle caña a iOS. Se debe hacer algo similar, y ese algo es WinRT y C++/CX. No hay máquina virtual .NET, ni nada oculto (o eso quiero creer), tan solo un motor de ejecución, una interfaz y el propio sistema operativo. O en otras palabras: objetive-c, cocoa y lo que quiera que haya en el núcleo de iOS (parece ser que un BSD recortadito).

Otro problema es la arquitectura. Ya se ha demostrado que x86 es demasiado pesado y demasiado hambriento de energía como para ser útil en el mercado móvil, por lo que hay que subirse al carro de ARM, que son micros mucho menos complejos y por tanto consumen mucho menos y andan más sueltos.

Por lo tanto se necesita algo diferente, algo mucho más liviano. Y eso, de nuevo, es WinRT. Por lo tanto, la combinación ganadora es C++/CX, XAML y, cómo no, C# y VB.NET corriendo sobre una variación de .NET llamada .NET 4.5 WinRT (y que funcionará más lento y consumirá más batería que una aplicación realizada con C++/CX).

Pero el núcleo, el centro de todo, es C++ y WinRT. Luego está .NET, encima igual que en Win32. Como debe ser. Y de nuevo absténgase fundamentalistas. Si lo han hecho por algo será. Quien cae del árbol a tiempo todavía puede recuperarse.

***

C++/CX no es .NET. Es nativo. Y la parte CX no es más que un envoltorio cómo para los interfaces COM, ese animal mitológico con el que los programadores de C++ nos tenemos que enfrentar de tiempo en tiempo y que nos pone los pelos de punta.

Es decir, la parte CX sólo se utiliza para interactuar con XAML y los componentes que se hayan creado a tal efecto. Luego, nuestro código será C++ normal y corriente, con la STL, los streams (que personalmente pienso que no son muy útiles), Boost o lo que queramos usar y esté disponible. Desarrollo determinista por completo, sin recolector de basura (a no ser que nos hagamos uno), sin elementos ocultos excepto el envolvente COM que han llamado CX y que nos servirá para interactuar con los componentes.

Otra ventaja de C++/CX sobre .NET es que, si quieres hacer un juego sobre DirectX, tendrás que usarlo ya que ni C# ni VB.NET están soportados, de nuevo como debe ser.

Ah, y con soporte para clases parciales, lo que… bueno, mejor lo dejamos para más adelante.

Code Complete 2, Steve McConnell

Ñas. Por fin lo he leído. Más de un año para acabarlo. Entre lo que os conté con mi jefe y la empresa, y cierto bajón existencial, dejé de leer temas técnicos, pero creo que he vuelto, o eso espero.

Bueno, al rollo.

Lo primero de todo, y pese a que me vais a llamar de todo, el libro no me ha aportado nada nuevo, salvo quizás en los últimos capítulos cuando habla de integraciones y manejo de grandes grupos de programadores, entre los que no me cuento. Es decir, o bien programo solo o bien en pareja o para un tercero, haciendo rutinas de bajo nivel o bibliotecas (DLL, como las llama mi jefe).

Lo único ha sido la sorpresa de encontrar veinte años de experiencia condensados en un solo libro. Y lo que falta, que no es poco. Pero bueno, lo cierto es que este libro tienes que leerlo.

Si no lo has hecho, cómpralo y ponte a ello, porque seguro que te va a resultar constructivo. Y si te dice cosas nuevas, vuélvelo a leer cada año o cada seis meses. O si eres de los que va despacio, cuando termines por una punta, cógelo por la otra.

Es increíble lo que pueden dar ochocientas páginas, pero lo dan.

Te pego una cita, sacada de aquí:

 

Si sólo tienes oportunidad de leer un libro sobre desarrollo de software en toda tu vida, procura que sea éste. Code Complete es prácticamente la biblia del desarrollo de software, además de una de las mejores guías prácticas sobre la programación de todos los tiempos. Es un libro muy fácil de leer, entretenido, y tremendamente práctico, con montones de recomendaciones útiles para cada fase del ciclo de vida del software. El simple hecho de leerlo te hará mejor programador. Seguro.

 

Con eso creo que basta.

El compilador como servicio

Me he quedado poco menos que estupefacto con esta entrada del blog de SomaSegar. Y no, no penséis mal, que no es malo.

Básicamente viene a decirnos que está disponible la CTP de “Roslyn”, que según entiendo es una extensión -de momento- a Visual Studio 2010 SP1. De hecho nos la podemos bajar y jugar con ella.

Comienza diciendo que los compiladores se han venido haciendo en C++ nativo, pero que ya es hora de cambiar y que han rehecho los compiladores de C# y de Visual Basic desde cero en… Visual Basic.

Hay que joderse. La primera en la boca. ¿Pero no decían que el compilador y el propio .NET estaban hechos en C# (lo siento, no encuentro la referencia)? Ahora no, ahora resulta que C# está escrito en C++.

Y la segunda, también: C# está hecho en Visual Basic.

O están tontos, o yo no me entero, o mienten más que hablan. Para nada me extraña de que hubieran mentido en lo de hacer C# en C++, de hecho es lo lógico y coherente, ¡pero construirlo todo en VB?

De todos modos dejemos esto aquí, corramos un estúpido velo, y centrémonos en el meollo del artículo: compilador como servicio.

Es decir, en Visual Studio 11 los compiladores de C# y VB no serán ejecutables, sino servicios expuestos al público (espero que haya uno para invocarlo desde la línea de comandos), de modo que cualquiera podrá compilar.

No solo eso, sino que dejarán de ser una caja negra que, a partir de un código fuente, genera una salida compilada, sino que podremos acceder a los diferentes estados del proceso de compilación, e incluso podremos realizar solo unos pasos, como análisis semántico o la obtención del código IL (ensamblador del .NET).

Eso posibilita la creación de scripts en una consola interactiva. ¿Recuerdan la consola aquella que tenía el Visual FoxPro que permitía ir encadenando comandos como si programáramos? Pues lo mismo, pero en VB y en C#. Vamos, que reinventan la rueda.

En la entrada original hay un par de imágenes enseñando lo que puede hacer.

 

Paragon HFS+ para Windows o cómo reventar un MAC

Cuando uno está en esto del switching indeciso, que no sabe si irse para Pinto o para Valdemoro, le pueden pasar cosas como la que os voy a contar.

Todos sabéis que desde hace unos años Apple permite la ejecución de Windows sobre su hardware compatible, y que suministra no sólo los drviers (que funcionan cojonudos), sino las herramientas necesarias para tener un arranque dual sin mucho problema. Por tener, hasta tenemos soporte de lectura para el formato de ficheros HFS+, con lo que veremos sin problemas las unidades del MAC, aunque no podremos escribir en ellas.

Una suposición personal es que, así, no podremos trastear en un sistema de ficheros en el que es peligroso tocar si no está cargado el sistema operativo. (Lo que viene a ser igual que con Windows, ya que si tenemos arranque dual, la instalación que no se haya iniciado podría ser fácilmente estropeada por algún zarpas, léanseme: yo mismo.

Pues bien, hasta aquí todo perfecto.

Supongamos ahora que queremos soporte de escritura. Porque somos así de chulos y así de molones, porque nosotros lo valemos. O simplemente porque tenemos una unidad de disco externo con nuestro MAC que también queremos usar en Windows.

Vale, la formateamos con FAT32 y listo. No os lo aconsejo. Aparte de que es un sistema de ficheros no muy robusto, carece de sistema de permisos y tiene otras limitaciones en cuanto a los nombres de los ficheros. Y si encima tienes ya ocupados unos cuantos gigas, como que se hace cuesta arriba la conversión.

¿Podemos escribir en HFS+ desde Windows? La respuesta corta es que sí. La larga es que mejor no lo hagas. Me explico.

Paragon Software Group cuenta con un driver para Windows (tanto de 32 como de 64 bits) que permite eso mismo: leer y escribir sin problemas sobre particiones HFS+. O eso dicen.

En mi caso ha sido un desastre total. No sólo me ha jodido la partición donde estaba el OS X (que no tendría mayor problema) sino que también ha destrozado otra sobre la que no estaba escribiendo, alojada en un disco externo por FireWire 800.

Me tocó reinstalar el OS X desde el DVD de Lion (porque de paso borré todo el disco interno del iMAC e hice una instalación limpia para ver si se me iban los problemas al actualizar a la 10.7.2) y olvidarme de los datos que había en el disco externo, algo así como medio Tera en máquinas virtuales, ISOs descargadas y otras copias de seguridad…

Así que ya sabéis, tomaos con calma el “HFS+ for Windows” y probadlo extensamente antes de pasar a producción.

iCloud o la flagrante tontería

¿Sabéis lo que es iCloud? Aunque digáis que sí, me juego un gallifante a que no. ICloud es una mierda envuelta en papel brillante, un trozo de bisutería rodeado de oro del que cagó el moro.

Acabo de comprobarlo. Tengo dos iMAC, un iPad, un iPod y un iPhone (este del curro, que todavía no he actualizado).

Como sabéis, hace unos días salieron todas las actualizaciones de golpe, tanto para el escritorio como para los dispositivos móviles. En mi caso la actualización a Lion 10.7.2 se realizó sin problemas, salvo una notable ralentización del sistema una vez reiniciado, ralentización que parece es temporal ya que ahora funciona todo casi igual de rápido que antes… excepto algún que otro rosetón multicolor de la muette que deja mi i7 de cuatro núcleos dobles y 12 GB de RAM como autista unos segundos… Eso no lo hacía antes de aplicar el parche.

No obstante, la actualización de los dispositivos móviles ha sido más que penosa. En primer lugar falló la descarga y la actualización. Me dio el infausto “internal error” causado por la caída de los servidores de Apple. Hay que joderse, con la expectativa generada y que la empresa no fuera capaz de preverlo con antelación. Joder, hasta Microsoft, el denostado Microsoft, cuando saca un producto nuevo que es muy esperado, aumenta y confía en terceros para las descargas…

Pero no todo termina ahí, no. El iPod se actualizó más o menos bien, a la tercera o la cuarta, pero el iPad hubo de sufrir bastantes intentos. O bien se quedaba autista o bien simplemente fallaba. Como tengo casi 40 GB de datos en él, y la interrupción se producía casi al final, la cosa llevaba su tiempo. Al final, restauración de fábrica, instalación de las aplicaciones y vuelta a meter los datos. Menos mal que soy un chico previsor y los tengo en el MAC, listos en sus carpetas. Eso sí, todavía estoy configurando programas…

¡Quietos parados, fanboys! A ver. Uno mete el iPad, te dice que tiene una actualización, le dices que sí, y a medias falla. No hay otra. No es mi culpa. Es de Apple. Por el motivo que sea. Mi iPad está impoluto, sin Jailbreak, sin cosas raras. Ya que está todo cerrado, debería funcionar a la primera, porque si no me vuelvo a Windows que me deja hacer lo que quiera sin más, y si falla puedo achacarlo a mi ineptitud, no a la de Apple. [Como colofón a esto, no soy el primero que ha tenido problemas. Básicamente la actualización a iOS 5 ha sido pésima. También quiero pensar que no se trata de un intento de que estampe mi iPad 1 contra la pared y me compre un 2.]

***

Bueno, ahora sí, ahora hablemos de la magia de la cosa esa del iCloud. ¿Os pensáis que es una versión mejorada de Dropbox? Juas, ni se le acerca. Hasta el infausto SkyDrive de Microsoft es mejor.

No, no es que vaya mal, es que no cumple mis expectativas. Es una decepción total, más que total, humillante. Lo único que te va a guardar iCloud son los documentos de Pages, de Office (a mi no me lo hace), tus fotos y los calendarios… pero los que crees en la nube. Es decir, la cacareada sincronización sólo se va a producir entre los documentos políticamente correctos que, como siempre, le vengan en gana a Apple. No mis documentos. No mis fotos ya hechas, no los documentos que yo quiera, no.

Y encima, como elemento de obsolescencia programada, si quieres tus documentos en la nube, paga por nuevas versiones que lo soporten. Asco me da. Decepción. Tristeza.

***

En serio, tengo una extraña sensación que me parece que, conforme va pasando el tiempo, es más fuerte y coherente: cuanta más cuota de mercado coge Apple, más se parece a los peores tiempos de Microsoft, con fallos estúpidos, dejadez en atender los requisitos de los clientes y olvidarse de que uno debe estar al loro con las actualizaciones de seguridad y que no debe esperar dos meses a, por ejemplo, invalidar una entidad certificadora. Es una especie de deja-vu, una sensación como de inquietud y de malestar… Ahora que Jobs ya no está, quizás la cosa mejore… aunque lo más seguro es que empeore.

Básicamente, maldita la hora en que me pasé a Apple.

Más sobre C++ AMP

Ya os comentaba en otra entrada del blog algo sobre la nueva biblioteca de paralelismo masivo llamada C++ AMP que traerá la nueva versión de Visual Studio, que ahora, tras el lanzamiento BUILD de hace unos días, se llama Visual Studio 11. Eso no quiere decir que vaya a salir este año, sino que se trata del número de versión. Si Visual Studio 2010 era la 10 (una mera coincidencia), la 11 quizás salga en 2012, más o menos cuando Windows 8.

 

Una pequeñísima introducción sobre C++ AMP

Es una biblioteca de C++ escrita para poder ejecutar código paralelo de forma independiente del hardware y a la vez aprovechar el hardware actual de los PC (léase procesadores multi núcleo y tarjetas de vídeo 3D) sin tener que complicarnos mucho la cabeza. También está pensada para aprovechar los futuros desarrollos de forma transparente para el programador.

También forma parte de Visual C++, por lo que no es necesario nada extra, y se encuentra perfectamente integrada en el producto, por lo que las tareas habituales como compilación y depuración son transparentes para el usuario.

Tan sólo necesita una extensión del compilador de C++ (el famoso restrict del que os hablé en la otra entrada), tiene una sintaxis similar a la de la STL, y es muy fácil trabajar con vectores multidimensionales de forma independiente del hardware.

Para los que no lo sepáis, una de las limitaciones de los procesadores SIMD (Single Instruction Multiple Data), que parafraseado podría ser Una Sola Instrucción Para Muchos Datos, está en su limitación respecto al tamaño de los arrays que pueden ejecutar de una sola tacada. Es decir, imaginaos que tenéis que rotar un cuerpo 3D compuesto por X polígonos. La rotación se puede hacer con una sola instrucción ejecutada para cada uno de los polígonos. Algo así como un bucle for que recorra todos y cada uno de ellos, aplicando la misma transformación. Con un SIMD, uno carga los datos en cada pipeline (o como se llame) y luego ejecuta la instrucción sobre todos ellos a la vez. El problema viene cuando tienes más polígonos que pipelines, y tienes que hacerlo a pedazos. Añade que el tamaño de cada pedazo no solo es diferente para cada procesador SIMD, sino también para cada versión (SIMD=Tarjeta de vídeo 3D). Con esta biblioteca te olvidas de todo eso. Ya lo hace ella sola.

Está basada en DirectCompute, una ampliación añadida a DirectX 11.

 

¿Puedo ejecutar C++ AMP?

Una opción es instalarte todo el tema (compilador, Direct X, etc) y probar a ejecutar un programa. Otra más sencilla es bajarte el programa que se describe en esta entrada y ejecutarlo. No requiere nada especial, y no usa C++ AMP para determinar si tu hardware lo permite o no.

En mi caso, ni el PC del curro, ni la máquina virtual, ni el portátil lo soportan. Pero sí mi PC principal, y seguro que el iMAC con Windows 8 instalado, que va a ser una de mis próximas tareas.

De todos modos, si el programa te dice que NO tienes hardware, no te preocupes, ya que la instalación del SDK de DirectX 11 o de Visual Studio 11 te creará un dispositivo emulado que no va a funcionar muy rápido que digamos, pero que al menos te permitirá ejecutar los programas.

Para aquellos vagos que no quieran leerse la entrada, o que simplemente no sepan inglés, aquí está el programilla.

 

Usando C++ AMP

Necesitas tener Visual Studio 11 en algún Windows (incluyendo la versión 8). Usar esto es tan fácil como incluir amp.h y añadir el espacio de nombre concurrency en tu proyecto. Ya está, ya puedes escribir código funcional.

Uno de los ejemplos más sencillos (y afuncionales) podría ser:

 

#include “stdafx.h”

#include <amp.h>

#include <iostream>

 

using namespace concurrency;

using namespace std;

 

int _tmain(int argc, _TCHAR* argv[])

{

cout<<acos(0.123456)<<endl;

return 0;

}

 

Lo que a todas luces sirve para poco pero nos permite ver que todo funciona bien, ya que la función acos viene dentro del espacio de nombres concurrency como podríamos comprobar si escribiéramos

concurrency::a

 

Y dejáramos al sistema de IntelliSense que se abra y nos muestre las funciones disponibles.

 

Más ejemplos

Un buen sitio para aprender más sobre esto, en pequeñas dosis, es el blog de Parallel Programming in Native Code, que es de donde yo he sacado todo esto. De todos modos, en esta entrada del citado blog tenéis algunos puntos de entrada: C++ AMP in a nutshell.

Otro ejemplo, que de momento no he podido ejecutar porque lo he compilado con Visual C++ 11 en un Windows 7 virtualizado, es el ejemplo del SDK de DirextX llamado “N-Body Simulation Sample” y que ha sido portado aquí.