Formato propietario DOCX
Mejorar el rendimiento de SQLite
Con el desarrollo de SQLite 4, el énfasis se está poniendo fundamentalmente en mejorar su rendimiento. Es una consecuencia lógica debida a su mayor popularidad, que la han hecho evolucionar como backend de datos de aplicaciones cada vez más complejas.
Hasta ahora, los esfuerzos se destinaban sobre todo a añadir nuevas funcionalidades, al mismo tiempo que mantenían el código lo suficientemente compacto, como para correr en plataformas con recursos hardware limitados.
En este sentido, algunas opciones de compilación nos permiten añadir funciones que por defecto no están activas tales como SQLITE_ENABLE_FTS4, SQLITE_ENABLE_RTREE o SQLITE_ENABLE_STAT4; mientras que otras, nos dan la oportunidad de mejorar su rendimiento: SQLITE_TEMP_STORE 2, SQLITE_THREADSAFE 2 y SQLITE_ENABLE_ATOMIC_WRITE.
Sin embargo es habitual que trabajemos con versiones precompiladas de SQLite, ya sea desde WebSQL, sobre las que no tenemos control en cuando a compilación. Para ello, el sistema nos ofrece ciertos PRAGMA, que permitirán ajustar su comportamiento en tiempo de ejecución, y así, mejorar su velocidad de ejecución.
Es interesante comprobar:
- PRAGMA journal_mode=MEMORY;
- PRAGMA journal_mode=OFF;
- PRAGMA synchronous=OFF;
Por supuesto, como buena constumbre, forzar el purgado, el reanálisis, y el reindizado cada vez que abrimos la base de datos, o preferiblemente cada vez que la cerremos, evitará que las prestaciones se degraden a medida que haya movimiento de datos. Os podéis dirigir a:
- VACUUM;
- ANALYZE;
- REINDEX;
Portabilidad
Como excusa para revisar los progresos de los snapshots diarios (27 MB en formato TAR.BZ2 vía FTP), decidí unificar los fuentes de 100 FPS en un PC (16 bits) y 500 FPS en un PC, para mostrar el funcionamiento del preprocesador de C, de cara a mantener la portabilidad entre plataformas.
El artículo pretendía explicar el uso de #define, #ifdef/#if defined, pero incitado de nuevo por los poderes ocultos de Watcom, me dediqué a ver hasta cuánto podía mejorar el original, sin necesidad de usar ensamblador. ¡Qué tiempos con el #pragma aux!
Lo primero que hice fue sustituir las llamadas a kbhit y getch, por una implementación directa basada en los servicios de teclado de la BIOS. Este cambio redujo en algunos bytes el tamaño final del ejecutable, al evitar enlazar con esas dos funciones de la RTL, y al reducir la sobrecarga del bucle, también aumentó levemente su rendimiento.
Después decidí que la versión de 16 bits usara el modelo de memoria small en vez de compact, esto aumentaría la velocidad de ejecución general, y reduciría también otro tanto el tamaño del programa. Lo malo es que para acceder a la memoria de vídeo, que está en otro segmento, se necesita un puntero far, y el uso de _fmemcpy.
Apliqué la optimización propagación de constante en el fragmento que asigna la paleta. Sorprendentemente era una optimización que Watcom no había aplicado demasiado bien, y de nuevo reducimos espacio, y ganamos algo de rendimiento en el proceso.
También sustituí printf por cprintf, que es más veloz y compacto, debido a que no soporta redirecciones DOS.
Para la versión de 32 bits, usé PMODE/WI 1.33, aunque no es tan potente como DOS32/A o DOS/4GW, era suficiente, y ahorró casi 20 Kb.
Finalmente ajusté un poco las opciones de compilación, y generé el código con Open Watcom 2.0 Beta, el resultado fueron ejecutables levemente más grandes.
Los resultados finales fueron:
16 bits:
- Versión original: 92 FPS / 78.122 bytes.
- Versión ajustada: 93 FPS / 71.632 bytes.
32 bits:
- Versión original: 180 FPS / 111.934 bytes.
- Versión original: 184 FPS / 87.188 bytes.
Es decir, una mejora de rendimiento de entorno al 2%, y de ahorro de espacio de entre el 9% y el 28%. Teniendo en cuenta que los ajustes llevaron casi el mismo tiempo que el desarrollo inicial, eso nos da una idea del coste de este tipo de mejoras.
Cabe destacar que si consideramos que casi 64 Kb. corresponden a datos, el código resultante de la versión optimizada de 16 bits quede reducido a apenas unos 6 Kb.
Lógicamente en cuanto a tiempo de ejecución, lo más eficaz habría sido reemplazar memcpy, en realidad el cuello de botella del programa. Paul Hsieh, tiene versiones muy interesantes, pero que parten de la base de o bien optimizar para una arquitectura concreta, o bien utilizar instrucciones extendidas tipo x87, MMX o SSE.
Ahora vamos a la parte de portabilidad. Si echáis un vistazo al código de abajo, veréis algunas novedades sobre las versiones anteriores.
Dentro del bloque de #if (defined(__FLAT__)), es decir modo flat, usado sobre DOS en modo protegido, veréis que:
- Se mapea int86 a int386: Una incómoda particularidad de algunos compiladores de 32 bits, donde la invocación de interrupciones usa dos versiones distintas, dependiendo del ancho de los registros.
- Se define far a nada: En modo flat, no hay direccionamiento far, y todo es near con punteros de 32 bits. El modificador far, es necesario para indicarle al compilador que los datos de la imagen en 16 bits, son lejanos y están en otro segmento. Es una consecuencia de usar la optimización del modo de memoria small, donde todo es near por defecto, y cuando no lo es, debe indicarse explícitamente.
- Se implementa la macro MK_FAR: A semejanza de MK_FP en modo real, crea un puntero de 32 bits en base a un segmento y un offset de 16 bits en modo real.
En modo real, es decir, cuando no está definido flat, lo que hacemos es:
- Mapeamos memcpy a _fmemcpy: _fmemcpy opera siempre con punteros far, así que es requerida cuando origen o destino sean lejanos. Por defecto el compilador utilzará las funciones adecuadas al modelo de memoria que estemos usando, de nuevo aquí, estamos mezclando el modelo de memoria small con punteros near, con punteros far, así que debemos declararlo explícitamente.
- Definimos MK_FAR: Een este caso, como un simple alias de MK_FP.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <conio.h> #ifdef __WATCOMC__ #include <i86.h> #else #include <dos.h> #endif #if (defined(__FLAT__)) #define int86 int386 #define far #define MK_FAR(seg, off) (((seg)<<4)+(off)) #else #define memcpy _fmemcpy #define MK_FAR(seg, off) (MK_FP((seg), (off))) #endif static unsigned char far gacPerin[]={...}; int main (void) { register unsigned int iX, iX3; union REGS udtRegs; clock_t clkStart, clkEnd; /* Modo 13 */ udtRegs.w.ax=0x13; int86(0x10, &udtRegs, &udtRegs); iX=0; for (iX3=sizeof(gacPerin)-768; iX3<sizeof(gacPerin); iX++) { outp(0x3C8, iX); /* El DAC espera los valores en el rango 0..63, por lo que debemos dividir cada uno por 4 (0..255). */ outp(0x3C9, gacPerin[iX3++]>>2); outp(0x3C9, gacPerin[iX3++]>>2); outp(0x3C9, gacPerin[iX3++]>>2); } iX=0; clkStart=clock(); do { /* Volcar al framebuffer 64000 bytes */ memcpy((unsigned char far *) MK_FAR(0xA000, 0), gacPerin, sizeof(gacPerin)-768); iX++; /* Comprobar pulsación de tecla */ udtRegs.w.ax=0x0100; int86(0x16, &udtRegs, &udtRegs); } while (udtRegs.h.al==0); clkEnd=clock(); /* Leer tecla del buffer */ udtRegs.h.ah=0x00; int86(0x16, &udtRegs, &udtRegs); /* Modo texto */ udtRegs.w.ax=0x3; int86(0x10, &udtRegs, &udtRegs); /* Mostrar en pantalla número de cuadros, y FPS */ cprintf("Frames: %d; FPS: %d\n", iX, ((long) iX*CLOCKS_PER_SEC)/(clkEnd-clkStart)); return(0); } |
El objetivo era que se entendiera la forma de trabajar con diferentes plataformas. Hemos visto que es sencillo, pero que se requiere un conocimiento previo sobre como trabaja cada una de ellas, de manera que podamos aislar las particularidad.
El resultado podemos considerarlo magnífico, un código más portable, más veloz, y más óptimo.
Puedes descargar el código fuente y los ejecutables aquí (101 Kb. en formato ZIP).
DOS/32 Advanced
Cuando preparaba el artículo Portabilidad, me di cuenta que dentro de contrib\extender\dos32a estaba todavía incluído DOS/32 Advanced 7.20, la versión en la que tuve mucho que ver. Como en MAME y yo, es algo que tenía hace tiempo olvidado.
A principios de 2000, con el abandono de Watcom C/C++ por parte de Sybase, y el subsiguiente anuncio de liberarlo como código abierto, fue una decisión que me entusiasmó, por lo que no es de extrañar que tuviera cierta implicación personal en aquellos años.
En 2001, con la primera versión 11.0c, me centré en los extensores DOS. Watcom soportaba una gran variedad de ellos, y no quedaba muy claro cual era el mejor, pero probablemente no era DOS/4GW. Así es como llegué a descubrir DOS/32 Advanced, un producto que por aquella época era comercial, extremadamente compacto (casi tanto como PMODE/W), pero muy rápido, estable y con bastantes funciones.
DOS32/A, había comenzado su andadura en 1996 como producto comercial desarrollado por Narech Koumar (Supernar Systems/SUNSYS), lamentablemente nunca llegó a cosechar el éxito que su calidad merecía. Así que cuando contacté con él en 2002, explicándole el futuro de Watcom, y la posibilidad de hacer una versión gratuita, enseguida concluyó que dado que ya no le reportaba ingresos, lo mejor sería hacerlo libre, y así es como salió DOS/32 Advanced 7.10 Liberty Edition.
Nos pusimos juntos a preparar la siguiente versión 7.2, creamos un espacio en el por entonces innovador Sourceforge y me dediqué a crear una nueva documentación, y más tarde como mantenedor oficial, ya que Narech no tenía mucho tiempo ni motivación para continuar desarrollándolo.
Así fui aplicando pequeñas mejoras, e integrando parches de Narech, hasta que oficialmente se publicó la versión 7.20 de 2002, ya como obra de el DOS/32 Advanced Team.
Lo comuniqué al equipo de Open Watcom, y estuvieron encantados de incluir el ahora opensource DOS32/A 7.20 como parte de Open Watcom 1.0 de 2003.
La versión 7.20, entre otros cambios, prescindía del instalador, cosa que a Narech no le gustó demasiado, y fue la única que se consideró como de la comunidad.
En 2005 volvió a tomar los mandos del proyecto, con las versiones 7.33 y 7.35, 9.1.0, y 9.1.1 también sin instalador, pero esta vez bajo la autoría de Narech Kontcell Todas eran bugfixes, salvo la 9.1.0, que demostraba con la cantidad de novedades que el proyecto había revivido. Finalmente en 2006, el proyecto quedaría congelado con la versión 9.1.2.
Durante aquellos años, ya no era un desarrollador activo en Open Watcom, y mis pequeñas colaboraciones en WASM y la CRTL se habían integrado hacía tiempo en la rama oficial, por lo que aunque insistí varias veces en que actualizaran el DOS32/A incluido en la distribución, nunca llegó a hacerse. Algo que me molestó en su momento, y que me alegra hoy en día, ya que si se hubiera actualizado, hoy no habría encontrado sus vestigios.
Por motivos históricos, y antes de que se pierda por completo, he decidido hacer una copia de la documentación y la web de 2003/2004, que podéis consultar aquí.
A continuación rescato el changelog completo, que incluye las actualizaciones relativas a la versión 7.2, incluyendo unos elaborados benchmarks, que muestran su capacidad y superioridad.
***************************************** *** DOS/32A DOS Extender -- ChangeLog *** ***************************************** [2006-04-20] DOS/32 Advanced DOS Extender, version 9.1.2 =========================================== DOS Extender (DOS32A.EXE): -------------------------- + Bugfix: Int 21h function 3Fh refused to return when reading from STDIN (reported by Gianni Gallucci) + Bugfix: in irq_fail fn, hardware exception #9 doesn't have exception code (reported by Charles Hyde) + applied mode.asm patch (also by Charles Hyde from Infineon) with minor formatting changes; I'm rather ambivalent about implementing the others into the mainstream builds (in particular the PAE one), will make those available from the development (beta) page... [2005-12-12] DOS/32 Advanced DOS Extender, version 9.1.1 =========================================== DOS Extender (DOS32A.EXE): -------------------------- + improved memory allocation under Clean system: INT 15h, AX=0E801h is used if AX=0E820h fails (based on patch provided by Arthur Kalliokoski) [2005-11-08] DOS/32 Advanced DOS Extender, version 9.1.0 =========================================== DOS Extender (DOS32A.EXE): -------------------------- + added support for SSE/SSE2/SSE3 capable processors + added preliminary support for PE file format (recognized but not yet implemented) + with verbose mode turned on the DOS Extender will pause prompting to press a key; this gives a chance to read loader info before the app kicks in + internal debugger has been dropped, CLIENT/debug.asm has been heavily rewritten + INT 1 and INT 3 op-codes are now treated by DOS/32A as no-ops, this works around some lame anti-debugging protections (Null-pointer protection works as expected) + "VCPI/DPMI Detection Order" option has been removed, DOS/32A unconditionally favours VCPI over DPMI, if and when possible + "Internal Exception Control" option has been removed, DOS/32A is always in control of the exception handling + "Trap and Report Emulated IRQs" option has been removed, this simplifies IRQ handling + "Extended Memory Blocks Checking" option has been removed, DOS/32A unconditionally checks EMB integrity + DPMITST environment option is no longer supported; it is still recognized but is now a no-op + whenever possible, DOS/32A will favour INT 15h/XMS systems over VCPI/DPMI, (thanks wd) + INT 31h DPMI last function entry is cached so that subsequent calls with the same function number do no search the lookup table + INT 31h DPMI functions 0E00h & 0E01h no longer virtualize FPU EM & MP flags + additional PIC constraint: slave PIC may not be mapped onto INT 8 + slightly reduced run-time complexity of the IRQ handling code + exception handlers are now invoked with the correct stack frame (as mandated by DPMI v0.9 spec) + all the exception vectors are now hooked under external DPMI (symmetric with built-in DPMI and using the same exception handlers) SUNSYS Setup Utility (SS.EXE): ------------------------------ + the following options in the Kernel menu have been deprecated: "VCPI/DPMI Detection Order" "Internal Exception Control" "Trap and Report Emulated IRQs" "Extended Memory Blocks Checking" it is still possible to toggle the state of these options, but the changes have no effect on the DOS Extender SUNSYS Debugger (SD.EXE): ------------------------- + R.I.P. [2005-05-19] DOS/32 Advanced DOS Extender, version 7.35 ========================================== DOS Extender (DOS32A.EXE): -------------------------- + mouse callback code cleanup + allocation of up to 2Gig under Clean system (Int 15h, AX=E820h) + with verbose mode active and not under external DPMI the entry point of application will trap to internal debugger [2005-01-12] DOS/32 Advanced DOS Extender version 7.33 ========================================= DOS Extender (DOS32A.EXE): -------------------------- + Bugfix: exec loader could crash the DOS Extender during startup in rare situations + Bugfix: DPMI function 0301h can not transfer data on stack to real mode procedure + Int 21h functions 4402h, 4403h, 4404h, 4405h, (DOS IOCTL) have been extended + Int 21h functions 3Fh & 40h (DOS IO) have been rewritten + mouse callback can now handle non-standard stack frames SUNSYS Bind Utility (SB.EXE): ----------------------------- + Bugfix: minor binding problems with unbound LE/LX execs + removed check for DOS32A environment string SUNSYS Compress Utility (SC.EXE): --------------------------------- + removed check for DOS32A environment string SUNSYS Setup Utility (SS.EXE): ------------------------------ + removed Lock and Version checks ******************************************************************************* Release 9 DOS/32 Advanced DOS Extender version 7.2 ======================================== News: ----- + Now Javier Gutierrez has the exclusive rights for using the DOS/32 Advanced name and in the main project mantainer. So, I am looking for contributors. + Improved a bit the build system. DOS Extender: ------------- + Applied Narech Koumar patch for the bug reported by Bart Oldeman on OpenWatcom newsgroups. + Recompiled using Watcom C++ 11.0c beta and Turbo Assembler 5.3. + Stubs now uses 8088/8086 instructions, so DOS/32 binded programs do not hang on those machines. Other: ------ + All utilities are linked against DOS32A. + Documentation has been improved, and is now compatible with Netscape 4.xx. ******************************************************************************* Release 8 DOS/32 Advanced DOS Extender version 7.1 ======================================== News: ----- + This release of DOS/32A is distributed under a new license. See "license.txt" for more information. + The complete source code of the DOS Extender and its tools is included with this release. DOS Extender: ------------- + Fixed bug in DPMI function 0503h when in certain cases the contents of the memory block being reallocated was not copied to the new location. + Minor fix: DOS/32A environment configuration option /NOWARN can now accept several warnings separated by a comma (eg /NOWARN:9003,9004). Other: ------ + Minor updates to the documentation manuals, mainly to reflect the new licensing issues. ******************************************************************************* Service Pack 1 (Revision [C]) DOS/32 Advanced DOS Extender version 7.0 ======================================== News: ----- + SVER Utility program. This utility can be used to find out the version of DOS/32A, STUB/32A or STUB/32C and to display the OEM Information appended to the LC-style executables by Original Equipment Vendors. DOS Extender: ------------- + Fixed problem in DOS/32A DPMI kernel causing the DOS Extender not being able to properly callback the IRQs of the second PIC to the protected mode handlers. SUNSYS Setup Utility: --------------------- + Fixed minor problem when in Kernel Config window setting VCPI PhysTables to 0 and switching to Hex mode caused the number to flash red incorrectly indicating an errorneously enered value. ******************************************************************************* Release 7 DOS/32 Advanced DOS Extender version 7.0 ======================================== News ---- + A new high performance D32A C/C++ Run-Time Library is now included with DOS/32 Advanced DOS Extender. The Library is located in .\L32 directory and its C/C++ header in .\H32 directory. + The documentation manuals supplied with DOS/32 Advanced DOS Extender are now in the HTML format. The plain-text based manuals have been dropped. To view the new HTML based manuals use an internet browser (Netscape Navigator is highly recommended although Explorer will also do fine), select "File -> Open File" from the browser's menu and open "manual.htm" file located in the .\DOCS directory. DOS Extender ------------ + Year 2000 compliance has been added for DOS/32 Advanced DOS Extender and all of the utilities accompanying it. + When running under _external_ DPMI host, DOS/32A will remove its own DPMI Kernel from memory, thus freeing up up to 10KB of conventional DOS memory. + Added exception handling under _external_ DPMI, DOS/32A will trap exceptions #0, #6, #13 and #14 (ie the most common) and report the complete machine state; DOS/32A will now also report where the exception came from by specifying "KERNEL" for ADPMI Kernel, "CLIENT" for DOS/32A Client, "APP/32" for the currently running application and "APP/??" if exception's origin is unknown. + Added support for "Performance Counters" which monitor the number of mode switches for INTs, IRQs, and Callbacks; a new Extended DPMI API function (AX=0A00h, then AL=09h) provides access to these. + Added support for protected mode TSRs installed with INT 21h, AH=31h function; contents of DX register passed to this function are ignored when called from protected mode. + Added new warning (9006): "incompatible version of DOS/32A already running" issued when the parent and the child applications are running under different versions of DOS/32A (when spawn() programs). + Added new environment option "/NOWARN:xxxx" to disable particular warnings, ie /NOWARN:9003. + Added new environment option "/NOC" to disable explictly the copyright banner. The warnings are still displayed on the screen. + Increased the maximum of loadable Objects from 32 to 64 per application. + Improved CTRL-C and CTRL-Break handling in the DOS Extender's Client code, which solves problems with these key combinations not properly detected when running under some external DPMI hosts (in particular Windows). + Improved Interrupt switching algorithm in DOS/32A DPMI Kernel, also improved algorithm enabling A20 gate when running in Clean system. + Improved error checking in Extended DOS functions 0FF95h and 0FF97h: they will now fail calls that allocate 0 bytes or >1MB. + Improved support for VCPI system software; fixed bug in VCPI initialization code which caused the DOS Extender's kernel to fail to free all the allocated PageTables on exit in some situations. You are now also allowed to set VCPI PhysTables value to zero to save some conventional memory if not using physical memory mapping DPMI functions 0800h and 0801h. + Minor fix: DPMI function 0001h (Free Selector) will now fail any calls that try to free the current CS (Kernel) or SS (App. stack) selectors. + Minor fix: Extended DOS function 4Ch (Terminate) will release ZERO selector before exiting to DOS. + Minor improvements in the LC-style file format loader: uncompressed Objects are loaded slightly faster. + Fixed bug in Extended DOS function AH=40h (Write to file) when DOS/32A would crash when running under external DPMI and writing to disk with no free space left. + Fixed bug in DOS/32 Advanced environment configuration reading functions, when the DOS Extender would sometimes at startup take off into "hyperspace" reading the whole environment, instead of just one line (DOS32A=...). + Removed check for invalid limits in DPMI function 0008h; DOS/32A will now unconditionally perform auto-correction of selector's limit if it is out of range. + Removed support for bottom-up allocation scheme when running under Clean (INT 15h) system software. Instead improved support for top-down allocation scheme which yields better performance and more extended memory. + Reduced the default number of Page Tables reserved for physical memory mapping from 4 down to 2 (eq 8MB). + Reduced the default size of DOS Transfer Buffer from 16KB down to 8KB, does not affect disk I/O performance but brings the memory requirements down. SUNSYS Bind Utility: -------------------- + Fixed all known problems. + Added support for OEM title information for LC-style execs. + Otherwise no major changes visible to the user. SUNSYS Compress Utility: ------------------------ + Fixed all known problems. + Improved (rewritten) "Advanced Preprocessing" algorithm. + Added support for OEM title information for LC-style execs. + Otherwise no major changes visible to the user. SUNSYS Setup Utility: --------------------- + Removed "Selector Invalid Limit Check" option. + Otherwise no major changes visible to the user. SUNSYS Debugger: ---------------- + No major changes. ******************************************************************************* Release 6 DOS/32 Advanced DOS Extender version 6.00 ========================================= News ---- + New SUNSYS Compress Utility program which allows compression of LE- and LX-style Linear Executables into the new LC-style Linear Compressed file format (see "sc.txt" help file located in .\DOCS directory). + Configurable stub file STUB/32C which can be configured by SUNSYS Setup Utility program, located in .\BINW directory and named "stub32c.exe". DOS Extender ------------ + Removed fatal error (0008): "configuration header corrupted", which was never used unless the DOS Extender was linked incorrectly. + Upon a crash (exception) in protected mode application the DOS Extender will report the unrelocated crash address for _any_ Object, not the only one that had entry point in it as it did before. + DOS/32 Advanced now supports allocation of more than 64MB of memory without using Virtual Memory. The maximum amount of memory the DOS Extender can allocate is limited to 2GB when running under XMS and to 256MB under VCPI. + Fixed problem with Verbose Mode when the DOS Extender would report the incorrect size of DPMI memory when allocated >64MB. The DPMI memory size is now reported in KB when below 64MB, and in MB when above. + Added support for LC-style Linear Compressed protected mode executables. By using SUNSYS Compress Utility the users can compress LE and LX applications into the new LC file format. + Added new run-time error (4007): "not enough DOS Transfer Buffer space to load LC-exec" which is reported when loading Linear Compressed executables and the size of DOS Transfer Buffer is set below 8KB. + The Loader will skip allocation of selectors for subsequently loaded 32bit Objects, and will make the application happy with only one 32bit CODE and one 32bit DATA selectors respective. This will prevent wasting of selectors in applications which contain more than two 32bit Objects. + DPMI functions 0602h and 0603h are supported and will return with CF clear without actually doing anything good. SUNSYS Bind Utility: -------------------- + Added new commands and options "/BC", "/RC", "/BN", "/UN", "/Q", "/S" and "/H" (or "/?"). Refer to "sb.txt" help file for more information. SUNSYS Compress Utility: ------------------------ + This one is new for this release. See "sc.txt" for help. SUNSYS Setup Utility: --------------------- + Added support for configurable stubs, STUB/32C files. + Added (actually documented) options "/INFO", "/LOCK", "/UNLOCK", "/QUIET", "/SILENT" and "/H" (or "/?"). See "ss.txt" help file. SUNSYS Debugger: ---------------- + Minor changes, fixed mouse problem with some mouse drivers when the cursor would disappear when moving it below the bottom of the screen. ******************************************************************************* Release 5 DOS/32 Advanced DOS Extender version 5.00 ========================================= DOS Extender ------------ + Resolved problem with WATCOM Linker v11.0(a) when the DOS Extender was not able to correctly recognize and load the LX-style executables. + The DOS Extender now supports, and will correctly load Objects with the size of zero. However, as such Objects will in most cases indicate an error in the protected mode application (wlink dead code elimination should kill'em), the DOS Extender will issue a new warning (9005) to inform the user about this situation. + The default size of the DOS Transfer Buffer is now 16KB instead of 64KB. This not only reduced the DOS memory requirements, but also improved the DOS Extender's disk I/O throughoutput. + When showing information about Selectors in the exception report listing the DOS Extender will no longer list the DPL of a Selector as it always was equal to 0. Instead, DOS/32 Advanced will show a better explanation of Selector's attributes (CODE/DATA and 16/32 bit). + DPMI function 0008h, Set Segment Limit, will now report invalid limits as a new run-time error (6006), which will result in application termination. You can always turn off this feature, by using the SUNSYS Setup Utility. + Fatal error (3005) will now report message "error in app exec" which means that the application was corrupted or an error occurred at link time. + With VERBOSE mode turned on the DOS Extender will now list the PSP_Sel, Env_Sel and Env_Seg to provide additional information about PSP Selector, Environment Selector and Environment real mode Segment allocated by the DOS Extender for application. In addition, the DOS Extender will report Process_ID and Module Name in the exception listing which can be useful when spawning applications. + Added new feature: "Start Full-Screen under Windows". DOS/32 Advanced will switch the application to the full-screen mode when running under Windows in a DOS-box window. Can be turned off (the default is off). + Another new option in the DOS Extender: "Ignore DOS/4G API Extension Calls". Documented in the "ss.txt" help file. Certain programs which otherwise use DOS/4G API extensions can now be run under DOS/32 Advanced. + The DOS Extender will now automatically deinstall the possibly installed mouse ISR by issuing INT 33h with AX=000Ch and ES:EDI=0 on exit to DOS. + New extended DOS functions 0FF94h..0FF97h are now supported for allocation of DOS memory. These functions work in exactly the same way as functions 0FF90h..0FF93h. Look into "Programmer's Reference" ("prog_ref.doc" file) documentation for more information about those. + The spawning techniques of DOS/32 Advanced have been greatly improved. The required size of the "DOS Transfer Buffer" is now 1KB instead of 4KB when using extended DOS function AH=4Bh to spawn. Read more about this in the "Technical Reference" ("rech_ref.doc" file) documentation. + Memory management ADPMI functions have been rewritten and now offer improved performance and security. Allocated Extended Memory Blocks are now aligned on Paragraph (16-byte) boundary and protection against EMB overwriting is now 99% safe. + Once again, DOS/32 Advanced DOS Extender requires no extended memory to load and execute a protected mode program. The relocations are now loaded into DOS memory first, only when not enough DOS memory, will they be loaded into extended memory (a very rare situation). + Fixed minor problem in DPMI functions 0800h/0801h when the last mapped page was not marked as last. + Fixed bug in extended DOS function AH=40h, Write to File, when truncation of files (using ECX = 0) did not work as expected. + Corrected DPMI function 050Ah, Get Base and Size of Memory Block. The base reported now points to the actual address of memory block instead of block header. + Fixed problem with IRQ 7 which was not processed by DOS/32 Advanced built-in DPMI correctly. + Fixed a small problem when the DOS Extender could not load and execute the "raw" LE/LX programs, ie applications not bound to any stub. + The ADPMI function 0EEFFh now returns EAX with "D32A" ID-string instead of "PMDW". This function has been pretty much standardized and can be used for effective detection of the currently running DOS Extender. + The Free Package version now supports DPMI functions 0800h and 0801h for mapping of linear memory. + Support for Win95 Long File Names has been included into this version of DOS/32 Advanced. Look for information on these functions (INT 21h, AX=71xxh) in the "Programmer's Reference" documentation ("prog_ref.doc" file). SUNSYS Setup Utility: --------------------- + Two new options have been added: "Ignore DOS/4G API Extension Calls" in the "Configure DOS/32A DPMI Kernel" menu, and "Start Full-Screen under Windows" in the "Configure DOS/32A DOS Extender" menu. + Several options have been renamed, and placed in a more proper (logical) order. You really should not have problems with recognizing them though. SUNSYS Bind Utility: -------------------- + Unbinding of LE/LX executables is now supported in the Free Package version. SUNSYS Debugger: ---------------- + Fully functional, except for the "System Interrupt History" which is supported in the Pro version only. Otherwise no major changes. ******************************************************************************* Release 4 DOS/32 Advanced DOS Extender version 4.30 ========================================= Install Program: ---------------- + The Install program will now automatically copy file "dos32a.lnk" into WATCOM's BINW or BIN directory (depending on which version of WATCOM C/C++ you have) if you select auto-system-update (which is strongly recommended). + You can now install DOS/32 Advanced in any directory, not just "DRV:\DIR" as it was before. You can install it for example in "C:\WATCOM\DOS32A" or anything like that. + File "dos4gw.exe" which was located in .\PCTEST directory has been removed to reduce the size of Compressed Data File. DOS Extender: ------------- + Bug fixed in DPMI function 0500h when the reported information was written to DS instead of ES selector (I know, I know...). + The DOS Extender will now correctly recognize and execute all types of DOS/4G(W) Professional bound applications. + Mode switching routines have been optimized for Pentium MMX/II and AMD K6 processors (or any CPU with multiple execution units supporting RISC86). This does not really improve mode switching speed though. + Bug fixed: the DOS Extender can now display decimal numbers greater than 0x7FFF within strings containing "%d" option. + DOS/32 Advanced now supports the "Verbose Mode". This one can be useful when you need to know exactly what is going on while the DOS Extender is loading your application, amount of allocated memory and so on. + New environment option: /VERBOSE[:ON|OFF]. Refer to the "User's Reference" ("user_ref.doc" file) documentation for more information. + New "undocumented" DOS API function AX=Magic. This function is mentioned somewhere in this package, but you will have to discover it yourself! SUNSYS Setup Utility: --------------------- + The Setup Utility now supports new option: "Verbose Mode". SUNSYS Bind Utility: -------------------- + The Bind Utility will now correctly recognize and process all types of DOS/4G(W) Professional bound applications. + Two new commands: "-BS", bind STUB/32A to a file, and "-RS" replace existing stub with STUB/32A, now supported. SUNSYS Debugger: ---------------- + The Debugger will now correctly recognize and load all types of DOS/4G(W) Professional bound applications. + The Debugger shipped with the Free Package version of the DOS Extender now supports all commands except "Here" (F4-key) and "Run" (F9-key). ******************************************************************************* Release 3 DOS/32 Advanced DOS Extender version 4.00 ========================================= News: ----- + Installation program that installs DOS/32 Advanced DOS Extender on your computer. + New stub file, 538 bytes in size! DOS Extender: ------------- + DOS/32 Advanced DOS Extender does not check for 8086 anymore. This should not be a problem since PC/XTs are quite dead nowdays. + DOS API function AH=0Ah is no longer supported and has been removed. It is not used in WATCOM libraries and nobody uses it anyway. + Support for Slow Object Loading Scheme has been dropped. The DOS Extender now requires some Extended memory in order to load application fixups, even if the application itself is loaded in DOS memory. + Error code (4004) has been changed: not enough extended memory to load application fixups. + Page Offset Shifts other than 0 are now supported by the loader for LX-style executables. + Fixed bug in startup code causing no errors being reported when protected mode was not entered successfully. + Fixed bug in exteded VBE API AX=4F00h when the CX register was not passed down to the real mode. + VBE API is now truly extended: function AX=4F00h now translates the pointers returned in the VBE structure to protected mode values. + New extended VBE functions have been added: AX=4F09h and AX=4F0Ah. + Bug fixed: options /QUIET and /PRINT:OFF defined in the environment now disable the copyright string (Pro version only) as well as warnings. + Bug fixed: on exit under "Clean" system the DOS Extender will not disable the A20 gate. This will solve problems when spawning programs with no memory manager installed, but this will also produce a problem with A20 line enabled after you run DOS/32 Advanced under "Clean" system. I guess we will have to live with that, since there ain't many programs that rely on memory wraparound under 1MB today, and you probably use a memory manager anyway. + Fixed a little bug in DPMI API function AX=0300h when parameters pushed on stack that were to be copied to the real mode stack were not being copied properly. + Bug fixed: extended DOS function AH=34h, get InDOS flag, will now work as expected (no GPEs or crashes no more). + Bug fixed: the loader was not able to correctly load the last object of the protected mode application, especially when the application was linked with debug info which was placed directly after the last object's data. An incorrect amount of bytes was read causing the _BSS segment being trashed while it should contain zeroes only (by default, WATCOM startup code will clear only the first 4K of _BSS segment if it thinks it runs under DOS/4GW). + Extended DOS API function AH=4Ch (terminate program), now will not restore real mode environment segment in PSP at offset 002Ch to be compatible with external DPMIs since they might need the protected mode selector at that offset to perform their cleanup on the way to DOS,.. or some place else. + Extended DOS API now supports new functions: AX=0FF8Ah, AX=0FF90h, AX=0FF91h, ... and so on (see "prog_ref.doc" file). SUNSYS Setup Utility: --------------------- + Option Use Fast Loading Object Scheme is no longer supported. SUNSYS Bind Utility: -------------------- + No major changes. SUNSYS Debugger: ---------------- + No major changes. ******************************************************************************* Release 2 DOS/32 Advanced DOS Extender version 3.00 ========================================= DOS Extender: ------------- + When a file name is specified at the command line, the DOS Extender will now apply an ".exe" extension to it, if it could not open the original file. This will solve some compatibility problems when replacing DOS/4GW DOS Extenders with DOS/32 Advanced. + The loader now supports Fast Object Loading Scheme. This feature allows the DOS Extender to load protected mode applications much faster (as fast as DOS/4GW does). Though it requires some extended memory to be allocated. Note that if no extended memory was allocated by the DOS Extender at startup, this feature will not be used, and the DOS Extender will automatically use the old, slow Object Loading Scheme, rather than reporting an error. + The loader now supports Paragraph (16 byte) alignment along with Page alignment (4096 byte) for objects that are loaded into extended memory. If a program has a large number of objects, this feature will greatly increase the amount of free extended memory available after the application was loaded. + Invented new DOS function in the DOS Extender: AX=0FF89h - DOS/32 Advanced Get Configuration Info (see "prog_ref.doc" file). + Invented new DPMI API function (AX=0A00h): AL=06h - Get DOS/32 Advanced Kernel Selectors (see "prog_ref.doc" file). + When spawning DOS/32 Advanced from another (incompatible) DOS Extender under VCPI, DOS/32 Advanced startup code will no longer cause the system to crash. + DPMI function 0500h will no longer return error 8013h when no extended memory was allocated at startup. Instead it will simply fill all the fields in the structure with zeroes. + DPMI function 0500h will no longer return the incorrect size of the largest available extended memory block as it did before in rare cases. SUNSYS Setup Utility: --------------------- + Option Console Output has been replaced with two new options: Show Warnings and Show Copyright Banner at Startup. + New option in DOS Extender Configuration window: Use Fast Loading Object Scheme. + New option in DOS Extender Configuration window: Object Alignment when Loaded High. + New option in DOS Extender Configuration window: Show Copyright Banner at Startup. This function replaces the old Console Output option, and allows the user to separately disable warnings (with Show Warnings option) and the copyright banner. SUNSYS Debugger: ---------------- + The Debugger now supports WATCOM-style assembly text screen along with Borland's Turbo Debugger-style. Use key '1' to switch between TD and WD text screens. ******************************************************************************* Release 1 DOS/32 Advanced DOS Extender version 2.25 ========================================= + The first publicly available version of DOS/32 Advanced DOS Extender.
FPS con BIOS
Después del artículo sobre Portabilidad, me apetecía retomar los programas y las técnicas de 500 FPS en un PC y 100 FPS en un PC (16 bits), para mostrarlo como sería el mismo proceso usando los servicios que ofrece la BIOS para video. Probablemente el método que usaríamos para implementarlo en una primera fase de aprendizaje.
La BIOS, Basic Input-Output System, hace de mediador entre el hardware, y el programador, ofreciendo servicios de bajo nivel que nos permiten acceder al mismo. A diferencia del acceso directo al hardware, el objetivo de BIOS es garantizar la compatibilidad. La idea inicial era que no importaba como estuviera diseñado un PC en concreto, siempre y cuando expusiera una interfaz común. Sin embargo, pronto se vería que las estructuras internas, tenían que ser idénticas también por lo que la BIOS perdió parte de su sentido inicial, quedando relegada a ofrecer un cierto grado de homogeneidad.
En efecto la implementación de los servicios de BIOS, no suele poner énfasis en el rendimiento, algo que vemos claramente con los resultados:
- Acceso al hardware: 5.952 KPíxeles/segundo (93 FPS).
- BIOS: 18 KPixeles/segundo (0,28 FPS).
Si habéis llegado hasta aquí, estaréis bastante sorprendidos con el resultado. Hablamos de una diferencia del orden de 250 veces más lento, así que vamos a matizarlo. Fijándonos en el bucle principal, nos damos cuenta que usando la BIOS, la única opción de volcar imágenes a pantalla es dibujando píxeles individualmente. Esto quiere decir que el proceso es mucho más complicado que mover 64.000 bytes de un sitio a otro como hacíamos en al artículo anterior, sino que requiere dibujar 64.000 píxeles cada vez, calculando para ello su posición en pantalla. Esto aspecto, explica en gran medida la diferencia de rendimiento.
Pero aún hay más. La función de Write Pixel, igual que el resto de funciones de la BIOS, soportan cualquier modo gráfico disponible. Es decir, el proceso para dibujar a otra resolución, o con otro número de colores, vendría a ser ensencialmente lo mismo, cosa que accediendo directamente al hardware, requeriría cambios mayores. Esta capacidad, implica que el sistema deba hacer comprobaciones adicionales antes de dibujar un píxel, lo que explica el resto de la diferencia en cuanto a rendimiento.
Precisamente esta flexibilidad que vemos, es la razón de que determinadas operaciones se realizaran también invocando a la BIOS, incluso en la anterior entrega. Por ejemplo asignar el modo gráfico, o comprobar el estado del teclado, podría haberse realizado también atacando al hardware directamente, no obstante habría sido más laborioso, y las ventajas en cuando a desempeño, habrían sido despreciables.
Otra característica de la BIOS, es la cantidad de servicios que nos ofrece, así por ejemplo usamos Set block of DAC registers, que nos permite asignar la paleta completa con una sola operación, y en este caso particular, con un rendimiento bastante aceptable. Es decir nos ha facilitado el trabajo.
Os dejo sin más con el código en cuestión:
#include <stdio.h> #include <time.h> #include <conio.h> #ifdef __WATCOMC__ #include <i86.h> #else #include <dos.h> #endif #if (defined(__FLAT__)) #define int86 int386 #define int86x int386x #define far #else #endif static unsigned char far gacPerin[]={...}; int main (void) { register unsigned int iX, iY, iPos, iCont; union REGS udtRegs; struct SREGS udtSegRegs; clock_t clkStart, clkEnd; /* Modo 13 */ udtRegs.w.ax=0x13; int86(0x10, &udtRegs, &udtRegs); /* El DAC espera los valores en el rango 0..63, por lo que debemos dividir cada uno por 4 (0..255). */ for (iX=sizeof(gacPerin)-768; iX<sizeof(gacPerin); iX++) { gacPerin[iX]=gacPerin[iX]>>2; } /* Asignar toda la paleta */ udtRegs.w.ax=0x1012; udtRegs.w.bx=0x00; udtRegs.w.cx=256; udtRegs.w.dx=FP_OFF(gacPerin+64000); udtSegRegs.es=FP_SEG(gacPerin); int86x(0x10, &udtRegs, &udtRegs, &udtSegRegs); iCont=0; clkStart=clock(); do { iPos=0; /* Volcar al framebuffer 320x200 pixeles */ for (iY=0; iY<200; iY++) { for (iX=0; iX<320; iX++) { udtRegs.h.ah=0x0C; udtRegs.h.bh=0; udtRegs.h.al=gacPerin[iPos]; udtRegs.w.cx=iX; udtRegs.w.dx=iY; int86(0x10, &udtRegs, &udtRegs); iPos++; } } iCont++; /* Comprobar pulsación de tecla */ udtRegs.w.ax=0x0100; int86(0x16, &udtRegs, &udtRegs); } while (udtRegs.h.al==0); clkEnd=clock(); /* Leer tecla del buffer */ udtRegs.h.ah=0x00; int86(0x16, &udtRegs, &udtRegs); /* Modo texto */ udtRegs.w.ax=0x3; int86(0x10, &udtRegs, &udtRegs); /* Mostrar en pantalla número de cuadros, y FPS */ cprintf("Frames: %d; KPixels/seg: %d\n", iCont, ((long) iCont*CLOCKS_PER_SEC*64)/(clkEnd-clkStart)); return(0); } |
Aquí (62 Kb. en formato ZIP), puedes descargar el ejecutable y su código fuente completo.
FPS con GRAPH.LIB
En la anterior entrega (FPS con BIOS), vimos el funcionamiento de los servicios de BIOS. Lo que hoy haremos será exactamente lo mismo, pero usando las bibliotecas bibliotecas gráficas del compilador, en nuestro caso graph.lib de Watcom C/C++, es decir, como nos enseñarían a hacerlo, incluso en la universidad.
El código tiene un aspecto bastante distinto. En vez de BIOS, usamos _setvideomode para asignar el modo gráfico, _remappalette para fijar la paleta de colores y la combinación de kbhit y getch para comprobar el estado del teclado. Sin embargo a nivel estructural es equivalente, y el dibujo se hace también sobre píxeles individuales, que requieren para cada uno de ellos una llamada a _setcolor y _setpixel.
Obtenemos los siguientes resultados:
- graph.lib: 17 KPixeles/segundo (0,26 FPS).
Que comparado con los resultados de los ejemplos anteriores, nos dan el peor rendimiento de todos:
- BIOS: 18 KPixeles/segundo (0,28 FPS).
- Acceso al hardware: 5.952 KPíxeles/segundo (93 FPS).
Vemos que estamos obteniendo un desempeño todavía peor que usando la BIOS. Es lógico, ya que la mayoría de lenguajes implementan gran parte de sus librerías usando los servicios de BIOS.
¿Qué ventajas obtenemos entonces? Es sencillo, las primitivas gráficas del compilador, disponen de funcionalidades listas para ser usadas, desde dibujo de lineas, que no es algo trivial, hasta gráficos, fuentes, polígonos, etc. Por tanto nos ahorran trabajo y errores, en comparación con desarrollarlas nosotros. Por otro lado,y al igual que con la BIOS, contamos con soporte universal de todos los modos de pantallas que se soporten, sin necesidad de modificar el código, y lo que es más importante, soporte de diferentes plataformas.
#include <stdio.h> #include <time.h> #include <conio.h> #include <graph.h> #if (defined(__FLAT__)) #define far #else #endif static unsigned char far gacPerin[]={...}; int main (void) { register unsigned int iX, iY, iPos, iCont; clock_t clkStart, clkEnd; /* Modo 13 */ _setvideomode(_MRES256COLOR); iX=0; for (iPos=sizeof(gacPerin)-768; iPos<sizeof(gacPerin); iX++) { _remappalette(iX, ((long) gacPerin[iPos++]>>2)+((long) gacPerin[iPos++]<<6)+((long) gacPerin[iPos++]<<14)); } iCont=0; clkStart=clock(); do { iPos=0; /* Volcar al framebuffer 320x200 pixeles */ for (iY=0; iY<200; iY++) { for (iX=0; iX<320; iX++) { _setcolor(gacPerin[iPos]); _setpixel(iX, iY); iPos++; } } iCont++; } /* Comprobar pulsación de tecla */ while (!kbhit()); clkEnd=clock(); /* Leer tecla del buffer */ getch(); /* Modo texto */ _setvideomode(_DEFAULTMODE); /* Mostrar en pantalla número de cuadros, y FPS */ cprintf("Frames: %d; KPixels/seg: %d\n", iCont, ((long) iCont*CLOCKS_PER_SEC*64)/(clkEnd-clkStart)); return(0); } |
Pero no acabamos aquí, porque como ya vimos en portabilidad, un conocimiento interno de como funcionan nuestras herramientas, puede ayudarnos enormemente. En este caso concreto a simplificar el código, y mejorar el rendimiento.
La mayoría de compiladores de C, pero también de otros lenguajes como Basic o Pascal, nos ofrecen funciones de manejo de sprites, en nuestro caso es _putimage, que tiene por finalidad dibujar una imagen en la pantalla. Desconozco el motivo, pero tanto la mencionada _putimage, como las implementaciones de PUT en Basic almacenan el bloque a dibujar con dos añadidos al principio, el ancho y el alto en píxeles del bloque. Así a la hora de dibujarlo, basta con especificar las coordenadas X e Y.
Modificamos nuestro ejemplo, e incluimos en el array gacPerin dos enteros cortos de 16 bits con sus dimensiones, antes de los datos propiamente dichos, y estamos listos.
#include <stdio.h> #include <time.h> #include <conio.h> #include <graph.h> #if (defined(__FLAT__)) #define far #else #endif static unsigned char far gacPerin[]={ 64, 1, /* Width: 320 */ 200, 0, /* Height: 200 */ ... }; int main (void) { register unsigned int iX, iCont; clock_t clkStart, clkEnd; /* Modo 13 */ _setvideomode(_MRES256COLOR); iX=0; for (iCont=sizeof(gacPerin)-768; iCont<sizeof(gacPerin); iX++) { _remappalette(iX, ((long) gacPerin[iCont++]>>2)+((long) gacPerin[iCont++]<<6)+((long) gacPerin[iCont++]<<14)); } iCont=0; clkStart=clock(); do { _putimage(0, 0, gacPerin, _GPSET); iCont++; } /* Comprobar pulsación de tecla */ while (!kbhit()); clkEnd=clock(); /* Leer tecla del buffer */ getch(); /* Modo texto */ _setvideomode(_DEFAULTMODE); /* Mostrar en pantalla número de cuadros, y FPS */ cprintf("Frames: %d; FPS: %d\n", iCont, ((long) iCont*CLOCKS_PER_SEC)/(clkEnd-clkStart)); return(0); } |
Los resultados:
- graph.lib (_putimage): 2.368 KPixeles/segundo (37 FPS).
Y recopilando las cifras anteriores:
- graph.lib (_setpixel): 17 KPixeles/segundo (0,26 FPS).
- BIOS: 18 KPixeles/segundo (0,28 FPS).
- Acceso al hardware: 5.952 KPíxeles/segundo (93 FPS).
Es decir, hemos conseguido obtener un rendimiento del orden de 2,5 veces más lento que accediendo al hardware directamente, y de 150 veces más rápido que usando _setpixel. No es nada despreciable, si consideramos que _putimage no está limitado a operar con la pantalla entera como hacíamos al usar memcpy, sino que es capaz de dibujar cualquier sprite rectangular, incluso con operaciones lógicas a la hora de volcar los píxeles individuales.
La conclusión de este artículo, y de momento de toda la saga, es que más importante que las técnicas y herramientas que se usen, es el conocimiento interno de las mismas, pudiendo enfocarnos hacia más simplicidad, flexibilidad, rendimiento, o tamaño, según nos convenga en cada caso.
Podéis descargar los dos códigos fuente y ejecutables del artículo aquí (145 Kb. en formato ZIP).
FPS en ensamblador
En FPS con GRAPH.LIB, habíamos concluido con el análisis y resultados de diferentes implementaciones gráficas en C bajo DOS.
Os adelantaba que en ensamblador la diferencia de rendimiento no iba a ser demasiado elevada, y que el motivo era que la implementación de memcpy, era ya muy eficiente en los compiladores de C.
Pero me apetecía probar Jwasm, por lo que a pesar de todo lo implementé en ensamblador. Me lo estaba pasando bien, así que le apliqué algunos trucos que espero que os resulten interesantes.
Lo primero es que estoy mezclando instrucciones de 8, 16 y 32 bits. En general lo más veloz es usar de 32 bits, pero éstas van a consumir más espacio y memoria, por lo que salvo que estuviera en un punto crítico, he usado el menor tamaño posible para hacer la operación.
He utilizado a propósito las macros de estructuras de control .repeat/.until. cuando fuera posible sin penalizar la eficiencia, y me hubiera gustado dar cabida a .if/.elseif/.else/.endif, .while/.endw, .repeat/.untilcxz, .break, etc, pero no ha sido posible.
Si he introducido otras macros que facilitan la lectura, y sobre todo el comenzar un programa desde cero: .code, .startup, .exit, rept, …
Gracias a lo compacto del código, que finalmente queda en 194 bytes, podemos conseguir algo que a priori puede parecer imposible. Hacerlo caber en un archivo COM, que por diseño están limitados a un total de 64 Kb. incluyendo código, pila y datos. Recordemos que solamente de datos gráficos se están manejando 64.768 bytes entre la imagen y su paleta. En este aspecto, si que ensamblador gana de calle, veámoslo:
- Ensamblador 16 bits: 64.962 bytes (código 194 bytes).
- Portabilidad C 16 bits: 71.632 bytes (código 6.864 bytes).
- BIOS C 16 bits: 71.672 bytes (código 6.904 bytes).
- Original C 16 bits: 78.122 bytes (código 13.354 bytes).
- Graph.lib 16 bits: 90.906 bytes (código 26.138 bytes).
Es decir, más de 100 lineas de listado, se acaban transformando en algo menos de 200 bytes de código máquina ejecutable. ¡Todo un logro!
Por supuesto ese resultado incluye interacciones con DOS, BIOS, hardware, e incluso una implementación simplificada de itoa para la conversión de números. Pese a que el programa se ensambla para DOS, la primera versión la desarrollé sobre Linux (Kubuntu 13.04), y la segunda sobre Windows (8 x64). Ventajas del ensamblado cruzado.
En cuanto a velocidad, ha anotado una marca de 185 FPS, no llega a ser un 1% más rápida que la versión de 32 bits posteriormente ajustada, dado que como anticipaba, el único beneficio viene de unas operaciones más eficientes a la hora de comprobar el teclado, y de usar registros que permite ensamblador, aunque la velocidad de volcado de frames, sea equivalente.
Un detalle curioso, que viene a colación, es que el programa funciona lógicamente en modo real, aunque use instrucciones i386 de 32 bits, es decir, eventualmente debería ser todavía más compatible que la versión en modo protegido, que requería un extensor DOS.
.model tiny .stack 64 .386 .data gacPerin db ... iStart dw 0 iStop dw 0 .code org 100h .startup ;Segmento ES apuntando a framebuffer mov ax, 0A000h mov es, ax ;Modo 13 mov ax, 13h int 10h ;Asignar toda la paleta xor cx, cx lea si, gacPerin[64000] .repeat mov dx, 3c8h mov al, cl out dx, al ;El DAC espera los valores en el rango 0..63, por lo que debemos dividir cada uno por 4 (0..255). mov dx, 3c9h rept 3 lodsb shr al, 2 out dx, al endm inc cx .until cx >= 256 ;cmp cx, 256; jb setpal ;Contador de inicio xor ah, ah int 1ah mov iStart, dx xor bp, bp ;frames en bp .repeat ;Volcar al framebuffer 320x200 pixeles lea si, gacPerin xor di, di mov cx, 64000/4 rep movsd inc bp ;frames++ ;Comprobar pulsación de tecla mov ah, 1 int 16h .until !zero? ;jz ;Leer tecla del buffer xor ah, ah int 16h ;Contador de fin xor ah, ah int 1ah mov iStop, dx ;Modo texto mov ax, 3h int 10h ;Escribir frames mov ax, bp lea di, gacPerin call itoa mov ah, 09h lea dx, gacPerin int 21h ;Escribir FPS mov ax, bp mov bx, 18 mul bx ;ax=frames*18 xor dx, dx mov bx, iStop sub bx, iStart div bx ;dx:ax=ax/(iStop-iStart lea di, gacPerin call itoa mov ah, 09h lea dx, gacPerin int 21h ;Salir a DOS .exit ;mov ah, 4ch; int 21h ;void itoa(char *pacbuffer = DI, int number = AX) itoa proc ;Vaciar buffer destino mov cx, 10 itoa_set0: mov [edi+ecx-1], byte ptr 0 loop itoa_set0 mov [di+10], byte ptr 10 mov [di+11], byte ptr '$' mov cx, 9 ;contador mov bx, 10 ;base .repeat xor dx, dx div bx ;edx=eax%10; eax=eax/10 add dx, '0' ;carácer mov [edi+ecx], dl ;dígito dec cx ; test ax, ax .until zero? ;jnz ret itoa endp end |
Podéis descargar el código fuente y el ejecutable aquí (57 Kb. en formato ZIP).
GIF clásicos
Los que vivimos el principio de la multimedia, recordamos como en los tiempos de DOS, intercambiábamos disquetes con imágenes de alta calidad, primero artísticas, y luego de otros tipos.
No existía todavía JPEG, que llegaría a principios de los 90, y no empezaría a popularizarse hasta algunos años después, de manera que nos conformábamos con el máximo de 256 colores basados en paleta que ofrecía GIF, y que para ser sinceros, ya nos parecían de calidad fotográfica.
Usábamos CSHOW (CompuShow), nacido en 1987, poco después de la primera versión del formato GIF, la 87a, y que iría evolucionando enormemente, dando soporte a 89a, y llegando hasta 1995.
Todas las imágenes que se compartían, tenían su origen en Compuserve, y llegaban a nuestras manos de un modo que me es imposible explicar, incluso ahora. Muchas eran simplemente imágenes de 8 colores, algunas de 16, otras de 32, 64, 128, pero la guinda eran las mencionadas de 256 (8 bits por píxel).
En aquellos equipos modestos, algunas nos asombraban con resoluciones de 640×400 o 640×480, que comprimidas en el eficiente para la época formato GIF, ocupaban varios cientos de Kb., y se decodificaban en algunos segundos. Sin embargo, las más populares eran 320×200, compatibles con gráficas MCGA y VGA, y que con algunas decenas de Kb. tenían suficiente. Además, al requerir solamente 64 Kb. una vez descomprimidas, hasta un equipo modesto era capaz de dibujarlas casi de inmediato.
Llegué a conservar del orden de 20 discos de 3,5 pulgadas con las más relevantes, y tuve amigos que tenían muchos más, así que recuerdo todavías las que más me impactaron: BALLOON, TIGER, CLOWN, BLUEYES, …
Claro que los tiempos han cambiado, y aunque son exactamente las originales, por motivos de eficiencia, las he convertido a PNG.
Breadbox Ensemble
En DOS en la actualidad terminaba la pequeña saga de tres artículos, dando un repaso superficial a Ensemble, del que creo que merece un mayor detalle.
Breadbox Ensemble, conocido anteriormente como Newdeal Office (1996-2000), y GeoWorks o PC/GEOS (1990-1994), con el permiso de Xerox, GEOS era el entorno gráfico probablemente más profesional para ordenadores de los años 80. No en vano, sus orígenes se remontan a 1986 cuando lanzaron la versión para Commodore 64/128.
Desde su primera versión contaba con multitarea preemtiva, y menú inicio, por lo que no es de extrañar que Microsoft se acercara a ellos para intentar adquirirlos mientras trabajaban sobre Windows 2.
Rápidamente se empezó a ver que su elaborado concepto y su magnífica implementación empezaban a llegar tarde a los 16 bits, y la competencia primeramente con GEM y posteriormente con Windows, iban dejándolo relegado.
Tuvo sus nichos de mercado con relativo éxito, como el PEN/GEOS del portátil de bajo coste de Brother, la que montaban los HP OmniGo, la versión para teléfonos inteligenetes Nokia 9000 y 9100, o GlobalPC, la versión que algunas operadoras de internet distribuían.
La última versión 4.13 de 2009, sigue la misma linea, y apenas aporta novedades sobre la 4.12 de 2005, o la 4.0 de 2002. A su vez éstas, son más bien funcionalidades menores comparadas con las de NewDeal Office 3 de 1999 o GeoWorks 2 de 1993.
Viendo lo que es ahora, y todo lo que ofrece, nos podemos hacer una idea de lo pionero que era Ensemble. Desafortunadamente es un producto más que podría haber llegado alto, si las circunstancias lo hubieran acompañado.
Entre la batería de aplicaciones incluidas, puedo mencionar: Base de datos (GeoFile), Blackjack, Buscador de archivos, Buscaminas, Calculadora, Calendario, Capturador de pantallas, Cliente de chat, Cliente FTP, Cliente de News, Contabilidad doméstica (Banker), Corazones, Correo electrónico, Diccionario, Dibujo (Artist), Editor de páginas web (WebBox), Editor de textos, Explorador de archivos, Gestor de archivos comprimidos (GeoZIP), Grabador de macros, Hoja de cálculo (Spreadsheet), Libreta de direcciones, Mahjongg, Mapa de caracteres, Mensajería instantánea, Monitor de rendimiento, Navegador web (WebMagick), Panel de control, Portapapeles (ScrapBook), Reloj, Procesador de textos (Writer), Poker, Reproductor de CD, Salvapantallas, Solitario, Visor de ebooks, Visor de imágenes, Visor de PDF, …
Con algo de tesón, podemos conectarlo a internet, y algunas cosas más, pero para ser sinceros, todo es algo peor de lo que aparenta. Y es que la mayoría de aplicaciones, no están debidamente actualizadas, así que los formatos que se utilizan son bastante antiguos, y por ende no interoperables con los actuales. Esto mismo, se extiende al navegador web, que aunque bonito, rápido y fácil de usar, está a mucha distancia de Arachne.
Os ofrezco para descargar algunos interesantes añadidos que he ido recopilando, y que os permitirán por un lado tener conexión a internet usando un packet driver, y por el otro disfrutar de las capacidades multitarea, o de intercambio de tareas de TaskMgr en Novell DOS y DR-DOS ( 12 Kb. en formato ZIP).
Quiero aprovechar la ocasión para dar las gracias a Frank S. Fischer (CEO de Breadbox) por ofrecerme una licencia de Ensemble; a John Howard (CTO de Breadbox) por los drivers para TaskMax/TaskMgr, y a Andreas (webmaster de geodb.org), por los drivers para packet.
Recuerdos de los 80
No estoy seguro de si los años 80 fueron una época en conjunto feliz, pero si de que fue una época llena de cambios. La tecnología empezaba a popularizarse en el mercado de consumo, avanzaba rápidamente, y España se abría al mundo, o al menos permitía que las novedades de fuera entraran.
Puede que la gente tuviera menos cultura, pero era más educada y respetuosa. El esfuerzo tenía recompensa, y por tanto había esperanza. Se les veía contentos gracias a la revolución que el futuro les deparaba, o eso es lo que pensábamos.
En pocos años pasamos de ver la tele en blanco y negro a tener una en color, poder grabar y reproducir usando una videograbadora (luego simplemente vídeo), o conectarla a un ordenador personal, que en aquellos años, era sensiblemente diferente a lo que IBM bautizó con el mismo nombre.
Íbamos al videoclub, y en el colegio nos intercambiábamos música y juegos de ordenador, sin saber que pagábamos un canon por copia privada, y sin plantearnos si era bueno o malo sacamos provecho a los equipos de música con doble pletina, y a los copiones. Cuando se terciaba, grabábamos canciones incompletas de la radio, habitualmente de los 40 principales. En el mejor de los casos los CD eran para música.
Disfrutábamos de nuestros ordenadores de 8 bits, aprendiendo mucho que todavía no se había inventado, y a la hora de jugar, lo hacíamos con imaginación y con “amigos en local”. Cuando la imaginación se quedaba corta, pasábamos la tarde en bares y salones recreativos, a los que no teníamos edad de entrar, pero en los que no pasaba nada, e invertíamos gran parte de nuestra paga en monedas de 25 pesetas en esos pequeños pedazos de placer que nos hacían soñar tan pronto mirábamos esos gráficos en la pantalla, esas luces, y ese espectacular sonido cuando se iluminaba el Credits 01. Agarrábamos el mando, y nos disponíamos a vencer a esas máquinas endiabladas que te engatusaban y jugaban de maravilla. Cuando el dinero se acababa, aprovechábamos para ver como otros jugaban, dando consejos, o memorizando pantallas y fases a las que no habíamos llegado.
El súmmum del entretenimiento personal, eran oficialmente las maquinitas tipo Game & Watch, o los Walkman, y otros de sus imitadores de asombrosa tecnología japonesa, pero podíamos pasarlo igual de bien parando el cronómetro con las centésimas a cero en un reloj Casio, viendo las rallas de la pantalla mientras un juego cargaba, o yendo con la bici en plan Michael Knight, o El halcón callejero.
Por la noche alucinábamos con los coches de Corrupción en Miami, y la espectacularidad y el artificio de 1, 2, 3. Si venían familiares o amigos a casa, raudos como el rayo montábamos el Scalextric, o el TCR.
Nuestro punto de encuentro era mucho menos respetuoso con la intimidad que Facebook, y eso ya es mucho decir, pues quedábamos en la calle, o en la plaza, incluso a las 4 de la tarde en agosto, impregnados de ese olor especial de calor, vacaciones, y verano. Aunque hubiéramos tenido la suerte de que nos regalasen una cámara fotográfica para nuestro cumpleaños, no solíamos llevarla nunca encima, y las fotos no se podían ver al momento, ni retocarlas con Instagram, o hacer previews.
A diferencia de hoy, los productos de calidad, lo eran porque duraban, y el que fueran comparativamente más caros que ahora, sólo hacía que cuando llegaban los disfrutásemos con mayor plenitud.
No había teléfonos inteligentes, pero las cabinas telefónicas eran lo suficientemente listas como para funcionar sin problemas, ni había Coca Cola Zero, ni descargas directas Bluray RIP, y en la nube sólo estaban los Osos Amorosos.
Así que cuando 30 años después me calzo las New Olimpo, pongo en mi muñeca el GW-M5610, uso las Wayfarer, lanzo Target Renegade u Operation Wolf en el Spectaculator, veo The Master, o escucho algún tema de Europe o Bon Jovi, muchas de esas sensaciones vuelven a aparecer, aunque sea por un instante, y entonces, soy algo más feliz.
Una de enlaces (II)
Seguimos con la recopilación de links en una de enlaces.
Bananabreed
Alucinante demostración de juego 3D multijugador en Javascript con WebGL.
Cinemagraph
Página dedicada a los cinemagraph, habitualmente GIF animados con técnicas cinematográficas.
Entrevista a David Leitch
Juegosa entrevista a David Leitch, el programador de la conversión ZX Spectrum de Double Dragon.
Junca Zapatos
Zapatería online, con unos precios de saldo.
node-webkit
Embede aplicaciones HTML en un ejecutable para Windows, Mac y Linux.
Pica Pic
Varios simuladores en Flash de maquinitas Game & Watch y similares.
Ohloh
Análisis de proyectos de código abierto, en términos de lenguajes utilizados, esfuerzo dedicado, lineas de código, …
PHP the right way
Manual con buenas prácticas de PHP, pero aplicadas al “mundo real”-
Cupones de descuento oficiales Burger King
Suculentas ofertas actualizadas regularmente, para que las aproveches cuando tengas que ir a un BK.
Por qué los precios en España no son igual que en Estados Unidos
Interesante artículo explicando el porqué un producto que vale 100$ en EE.UU, se vende a como mínimo 100€ en España. Centrado en los relojes, pero válido para cualquier producto electrónico.
Valentina Studio
Un frontend gratuito de gestión de base de datos, disponible para Windows, OS/X y Linux, con soporte de MySQL, SQLite, PostgreSQL, …
Spammers “inteligentes”
Seguramente habréis notado un incremento en la cantidad de spam, que recibís, y que está redactado de una manera en la que parecen mensajes legítimos. Su existencia es ya de por si engorrosa, ya que implica al menos una lectura superficial del mismo de cara a determinar si es spam o no lo es.
La lucha entre el spam y el antispam, ha sido continua como cualquier lucha. Si hago memoria, el primer paso que dieron los spamers fue evitar las palabras malas, entonces en vez de Viagra, escribían VIagra o cualquier otra variación. La contramedida de los filtros antispam fue detectar de manera heurística ciertas variaciones.
El siguiente paso evolutivo fue mandar el spam como una imagen que contenía el mensaje promocional, de nuevo duró poco, los clientes de correo desactivaron por defecto las imágenes, incluyeron una proporción entre contenido gráfico y textual, que si se superaba, advertía de probabilidades de spam, y en los casos más avanzados, incorporaron reconocimiento de imágenes (OCR).
El último paso que llevo apreciando desde hace algunos meses son contenidos de texto, pero que parecen redactados por una persona, y tienen cierto sentido. Son muy variados, así que los filtros Bayesianos pierden eficacia, y al ser textuales, tampoco los OCR.
Gracias a que en mi blog, he recibido un comentario de este tipo, pero supuestamente publicado con una herramienta que tenía algún error, he podido determinar su funcionamiento.
Este era el contenido del comentario:
{ { Tengo | He estado } { surf | } navegación en línea de más de tres { | 3 | 2 | 4 } horas de hoy , sin embargo, nunca ha encontrado ningún artículo interesante como la suya . { Es | es } bastante valor suficiente para mí. { En mi opinión | Personal | En mi opinión } , { si todos los propietarios de sitios web | webmasters | propietarios de sitios web | propietarios de la web } y blogueros hicieron un buen contenido como lo hizo , la { internet | net | web} { será mucho más | mucho más } útil que nunca. | I { podía no | no pude resistir } { | } se abstenga de comentar . { Muy bien | Perfectamente | Bueno | Excepcionalmente bien } written ! | { Haré | Voy } { inmediato | inmediatamente } { afianzarse de | Agarradera | Embrague | | comprensión apoderarse | arrebatar su { } rss | feed rss } como { no puede | no } { en la búsqueda | buscar | encontrar su } {email | e -mail } suscripción {link | hipervínculo } o { newsletter | boletín } servicio. Haga { tienes | } tienes alguna? { Por favor | bondadosa } {allow | licencia | let me } { cuenta | reconocerá | Conoce | reconozco | conocer } { para que | a fin de que } I { sólo puede | mayo | } podría suscribir. Gracias . | { Es | es } { apropiada | perfecto | el mejor } tiempo para hacer algunos planes para el futuro y { es | es } tiempo para ser feliz. { Tengo | Tengo } leer este post y si pudiera me { querer | querer | } deseo de sugerir algunas { | } algunas cosas interesantes o { consultoría | sugerencias | consejos } . { Quizá | Tal vez te } { podría | } puede escribir artículos siguientes se refieren a este artículo. I { quiero | querer | } deseo de leer más { | } aún más cosas sobre él ! | { Es | es } { apropiada | perfecto | el mejor } tiempo para hacer {a pocos | algunas } planes para { el futuro | largo plazo | A largo plazo } y { es | es } tiempo para ser feliz. { Tengo | Tengo } { leer | Aprender } { este post | enviar | publicar | aguanto } y si { sólo puede | Mayo | podían } I { querer | querer | deseo } { sugerir | recomendar | consejo } que { pocas | algunas } { interesante | fascinante | llamativo cosas } { | } o { temas consultoría | sugerencias | consejos } . { Quizá | Tal vez te } { podría | puede escribir { } siguiente | subsiguientes } { artículos relativos a | refiriéndose a | } con respecto a este artículo. I { quiero | querer | deseo } { leer | Aprender } { más | más cosas } { | } { aproximadamente cuestiones | } sobre él! | { Tengo | He estado } { surf | navegación } { online | on- line } { más | mayor } { tres | 3 } { hora en estos días | actualidad | Hoy | ultimamente | en los últimos tiempos } , { sin embargo, | I { } pero nunca | de ninguna manera } { encontrado | descubierto } { cualquier interés | fascinante | llamativo } artículo como el tuyo . { Es | es } { lovely | bastante | hermosa } { pena | Valor | price} { suficientemente | } suficiente para mí. { En mi opinión | Personal | En mi opinión } , { si todos los propietarios de sitios web | webmasters | propietarios de sitios web | propietarios de sitios web y bloggers hecho } { justo | bueno | excelente } { contenido | material de contenido } como { que hicieron | probablemente hizo } , { el internet | net | web} { será | será | puede ser | probablemente será | puede | probablemente será } { más | mucho más útil } { | } útil que nunca. | Ahaa , su { Niza | agradable | bueno | fastidioso } { discusión | CONVERSACIÓN | diálogo } { sobre | acerca | sobre | sobre el tema de este } {article | Poste | pieza de escritura | punto } { aquí | en este lugar } en este { blogs | blog | página | Página web | sitio web} , he leído todo lo que , por lo que ahora { | } en este momento yo también comentando aquí { | } en este lugar . | Estoy seguro de que este {article | Poste | pieza de escritura | punto } ha tocado todos los usuarios de internet { | personas | | televidentes visitantes } , es realmente muy bonito { | agradable | bueno | fastidioso } {article | Poste | pieza de la escritura | punto } en la creación de nueva { blogs | blog | página | Página web | sitio web} . | Wow , este {article | Poste | pieza de escritura | punto } es { Niza | agradable | bueno | fastidioso } , { mi hermana | hermana menor } { está analizando tal | | estos este tipo de cosas } , { para | por lo tanto | Por lo tanto } voy a decirle { | informará | hacer saber | transmitir } ella. | { Guardado como favorito | marcador ! } , { Me gusta | Me gusta | Me encanta tu blog } { | su sitio | sitio web | su sitio web !} | Way cool! Algunos { muy | extremadamente } puntos válidos ! Aprecio que { escribiendo esto | escribiendo este artículo } { | Poste | write- up} { y | y el | } más el resto del sitio es { | } { sitio web es también muy | muy | muy | También me | } muy bueno. | Hola , { sí creo | Pienso } { esta es una excelente | esta es una gran } { blogs | sitio web | sitio web | site} . I StumbledUpon it { haré | Voy a | Voy a | I puede } { volver | volver | volver } { nuevo | } { vez desde que | Desde que tengo } { marcado | Revista marcado | libro – marca | guardado como favorito } él. El dinero y la libertad es la mejor { | } es la mayor forma de cambiar , usted puede ser rico y seguir { Ayuda | guía } { demás | Otros } . | Woah ! Soy muy cariñosa { | disfrutando | excavación } la plantilla / tema de este sitio de { | Página web | Blog } . Es simple, pero eficaz . Muchas veces es muy difícil { | difícil | difícil | duros | difícil | } duro para conseguir ese ” equilibrio perfecto ” entre { excelente facilidad de uso | facilidad de uso | usabilidad } y { apariencia visual | atractivo visual | aparición } . Debo decir que has { | Tiene | has hecho } a { impresionante | asombrosa | Muy bueno | excelente | fantástica | excelente | } gran trabajo con esto . { Además | Adicionalmente | } También , las cargas de blogs muy { | extremadamente | súper rápido } { | } rápido para mí en { Safari | Internet Explorer | Chrome | Opera | Firefox } . { Superb | Excepcional | Destacado | Excelente } Blog ! | Estos son realmente { | realidad | hecho | verdad | genuinamente } { grande | gran | impresionante | maravilloso | fantásticos } { ideas en relación con | acerca | sobre | sobre el tema de los blogs } . Has tocado alguna { Niza | agradable | bueno | fastidioso } { puntos | | Factores cosas } aquí . De cualquier manera mantenerse al día wrinting . | { Amo | me gusta | Me gusta | Me gusta | Todo el mundo ama lo que ustedes } { sois | suelen | } tienden a ser demasiado . { Este tipo de | Este tipo de | Tal | Este tipo de } trabajo inteligente y { exposición | Cobertura | informe } ! Sigan con el excelente { | excelente | Muy bueno | gran | bueno | awesome | fantástica | excelente | increíble | } maravillosa funciona chicos que he incorporado { | | agregado | incluyó } ustedes a { | mi | nosotros | | Mi personal | mi } blogroll . | { Hola | Hola | Hola | Hola | Hola | } Hey ! Alguien en mi { Myspace | Facebook } { grupo compartió esta página | Página web } con nosotros, así que vine a { darle un aspecto | revísela | visita | comprobarlo } . Definitivamente estoy disfrutando { | } amorosa la información . Estoy { libro – marca | bookmarking } y estaré twitteando esto a mis seguidores ! { Terrific | Wonderful | Gran | Fantástico | Destacado | Excepcional | Excelente | Excelente blog y } { maravilloso | excelente | brillantes | asombrosa | gran | excelentes | fantástica | excelente | } { excelente estilo y diseño | diseño y estilo | diseño } . | { Amo | me gusta | Me gusta | Me gusta | Todo el mundo ama lo que ustedes } { sois | suelen | } tienden a ser demasiado . { Este tipo de | Este tipo de | Tal | Este tipo de } trabajo inteligente y { exposición | Cobertura | informe } ! Sigan con el excelente { | excelente | Muy bueno | gran | bueno | awesome | fantástica | excelente | increíble | } maravillosa funciona chicos que he incorporado { | Agregados | incluyó } ustedes a { | mi | nosotros | mi personal | mi propia } blogroll . | { Hola | Hola | Hola | Hola | Hola | } Hey , ¿te importaría { afirmando | compartir } que el blog plataforma que está trabajando con { | } usando ? Estoy mirando { | Planificación | yendo } para iniciar mi propio blog { en un futuro próximo | pronto } pero estoy teniendo un duro { | difícil | disco } { hora de tomar una decisión | seleccionar | eligiendo | } decidir entre BlogEngine / WordPress/B2evolution y Drupal. La razón que pido es porque su diseño y estilo { | diseño | diseño } parece diferente a la mayoría de los blogs y estoy buscando algo completamente único { | } única . PS { Mis disculpas | Disculpas | No } para { consiguiendo | es } off -topic , pero tuve que preguntar! | { Hola | Hola | Hola | Hola | Hola | } Hey , ¿te importaría dejarme saber que { webhost | empresa de alojamiento | alojamiento web } { usted está utilizando | trabaja con | usando } ? He cargado un blog en 3 { completamente diferente | distinto } { navegadores de Internet | Navegadores web | Navegadores } y debo decir que este blog se carga mucho más rápido { | } más rápido que la mayoría. ¿Puede sugerir { | } recomendar un buen recibimiento internet { | web hosting | Alojamiento } proveedor a { honestos | razonables | } justo precio? { Muchas gracias | Felicitaciones | Saludos | Gracias | Muchas gracias | } Gracias , se lo agradezco ! | { Amo | Me gusta | Me gusta | Todo el mundo ama } { que cuando la gente | cuando las personas | cuando la gente | cuando las personas se unen } { | } reunirse e intercambiar opiniones { | pensamientos | visitas | Ideas } . Gran { blogs | sitio web | site} , { mantenerla | continuar el buen trabajo | aferrarse a él !} | Gracias por el auspicioso { | } que buena valoración crítica . Es , de hecho, era una cuenta de atracciones ella. Mira avanzada para el momento { | } añadido más agradable de usted ! { Por cierto | } Sin embargo , ¿cómo podemos { | } nos podíamos comunicar? | { Hola | Hola | Hola | Hola | Hey } sólo quería darle una rápida cabezas para arriba . El texto { | } palabras en su { contenido | post | article} parecen estar funcionando fuera de la pantalla en { Ie | Internet Explorer | Chrome | Firefox | Safari | Opera } . No estoy seguro de si se trata de un formato { | } formateo problema o algo que ver con { navegador de web | explorador | explorador } compatibilidad pero { pensamiento | } pensé que había puesto para hacerle saber . { El estilo y diseño | diseño y estilo | diseño | diseño } ven muy bien ! Esperanza usted consigue el problema { | } { tema solucionado | resolvió | fijos } pronto. { Felicitaciones Saludos | | | ¡Muchas gracias Gracias } | Este es un tema { es | que es | que es } { cerca | cerca de mi corazón … } { Saludos | | ¡Muchas gracias Mis mejores deseos | Cuida | ¡Gracias !} { Dónde | ¿Exactamente dónde } son sus datos de contacto , aunque? | Es muy { fácil | sencillo | problemas | sencillo | sin esfuerzo } para encontrar cualquier { tema | materia } del { net | web} en comparación con { libros | libros de texto } , como descubrí este {article | Poste | trozo de escritura | punto } { en este sitio web | sitio web | página | Página web} . | ¿Su sitio de { | Página web | Blog } tiene una página de contacto ? Estoy teniendo un momento difícil { | Problemas | } localizar problemas , pero , me gustaría enviar { | } rodaje que una {e – mail | email} . Tengo algunas ideas creativas { | recomendaciones | sugerencias | } Ideas para tu blog Quizás se encuentre interesado en escuchar . De cualquier manera , un gran { página | Página web | Blog } y espero a ver que el desarrollo de { | mejorar | ampliar | } creciendo con el tiempo. | { De Hola | Hey allí | Hola | Hola | } Saludos ! He estado { siguiente | lectura } { su sitio | sitio web | sitio web | blog | Blog } de { mucho tiempo | poco | tiempo } ahora y finalmente consiguió la valentía { | } coraje para seguir adelante y darle un grito hacia fuera a partir de { New Caney | Kingwood | Huffman | Portero | Houston | Dallas | Austin | Lubbock | Humble | Atascocita } { Tx | Tejas } ! Sólo quería decirte { | Mención | Di } { mantener la fantástica | excelente | gran | buena } { trabajo | trabajo } ! | Saludos desde { Idaho | Carolina | Ohio | Colorado | Florida | Los angeles | California } ! Estoy { aburrido hasta las lágrimas | aburrido hasta la muerte | } aburrido en el trabajo , así que decidí { revisa | examinar } { su sitio | sitio web | Blog } en mi iphone durante el almuerzo . I { disfrutar | me gusta | amor } de { conocimiento | info | Información } que { present | proporcionará } aquí y no puedo esperar para echar un vistazo cuando llegue a casa . Estoy sorprendido { | asombrados | } sorprendido de lo rápido { | } rápido tu blog cargado en mi { móvil | teléfono celular | teléfono} .. Ni siquiera estoy usando Wi-Fi, 3G solo .. { Modos | De todas formas } , { impresionante | asombrosa | Muy bueno | excelente | bueno | maravilloso | fantástica | excelente | } { gran sitio | Blog } ! | Su { como usted | como usted} { leer | Aprender } { Mente | mis pensamientos } ! Usted parece { | } { aparecer entender | saber | captar } { mucho | mucho } { aproximado | ¿Quiénes } esto, { como usted | como usted} escribió el libro { | e -book | Guía | ebook | e } en el libro o algo . { Pienso | Siento | Creo } { que | que simplemente | que acaba } { podría | } puede hacer con un poco de { | a pocos } {% | PC | ciento } a { forzar | Presión | coche | potencia el mensaje } { casa | home } { un poco | un poco } , { embargo | } { pero aparte de | en lugar de que } , { es | es } { grande | maravilloso | fantástica | magnífico | excelentes } blog. { Una gran | Un excelente | Un fantástico } ver . { Voy | Yo } { Definitivamente | } sin duda , volveremos. | Visité { múltiple | muchos | varios | } { varios sitios web | sitios | Sitios web | páginas web | blogs } { pero | excepto | } sin embargo la calidad de audio { | } función de las canciones de audio { actual | actualidad | } existente en este { sitio web | sitio web | página | Página web} { es verdad | realidad | hecho | verdad | genuinamente } { maravilloso | maravilloso | excelente | fabulosa | soberbia } . | { Hola | Hola | Hola | Hola } , leí tu blog { ocasionalmente | de vez en cuando } y soy dueño de uno similar y yo estaba pensando { | } curioso si se obtiene una gran cantidad de correo no deseado { comentarios | respuestas | comentarios | comentarios } ? Si es así ¿cómo evitar que { | reducir | stop | protegerse } que , cualquier plugin o cualquier cosa que puedas { Consejo | sugerir | recomendar } ? Tengo mucho últimamente me está volviendo loca { | loco | loco } { por lo que cualquier ayuda | Ayuda | ayuda } es muy apreciada . | ¡Saludos! { Muy útil | Muy útiles consejos } { dentro de esta | en este particular, } {article | Poste } ! { Es | Son los pequeños cambios } { | que hacen que harán | | que producen que harán } { el mayor | el mayor | | el más grande de los más importantes | los más significativos cambios } . { Muchas gracias | Gracias | } Muchas gracias por compartir! | { Realmente | Sinceramente | Yo en serio | Estoy totalmente } { encanta tu blog | sitio | su sitio web .. } { Very nice | Excelente | Pleasant | Grandes } colores y temáticas. ¿Usted cree { | desarrollo | hacer | build } { este sitio | este sitio | este sitio web | este sitio increíble } a ti mismo ? Por favor, responda de nuevo a mí en busca de { | intentando | planificación de | queriendo | esperando | intentar crear } { mi | mi propio | mi cuenta personal } { blogs | sitio web | sitio } y { quisiera a | ¿quiere | encantaría saber } { | aprender | averiguar } dónde sacó esto de lo que el o { | exactamente lo que el | lo que el tema de { } se llama | se nombra } . { Gracias | Muchas gracias | Gracias | Saludos | apreciarlo | Kudos } ! | { Hola | Hola | } ¡Hola ! Este { post | artículo | post } { podría no | no } podría ser escrita { mejor | mucho mejor } ! { Leyendo | Mirando | Pasar por | Mirando a través de este } { post | article} Me recuerda a mi compañero de cuarto anterior! { Él siempre | continuamente | continuamente } { mantuvo hablando | } predicación sobre esto. { Haré | Voy | Voy a | ¡Por supuesto que va hacia adelante } { | } { Enviar este artículo | esta información | este post } para él. { Bastante seguro | Bastante cierto } { él | Estará | que va a } { una buena | tener un muy buen | } tienen una gran lectura. { Gracias por | Gracias por | Muchas gracias por | os agradezco for} compartir! | { Wow | Whoa | Incredible | } increíble ! Este blog se ve exactamente { | } simplemente como mi viejo! Está en una { completo | completo | totalmente diferente } { tema | subject} pero tiene más o menos la misma { diseño | diseño de la página } y diseño. { Excelente | Wonderful | Gran pendientes | Superb } elección de los colores ! | { No | No } { Definitivamente | Ciertamente } { mucho | mucho que } { Consciente | conocer | averiguar } { este tema | Tema | tema } . { Me gusta | I love | me gusta } { todo el | todos los puntos } { hiciste | has hecho | realizada } . | { Hiciste | Ha hecho | Usted ha hecho algunas } { decentes | | buenos muy buenos } puntos allí. Yo miré { | } { comprobé en Internet | sobre la web | en la red } { para más info | más información | saber más | aprender más | } para obtener más información sobre el tema y encontró la mayoría de las personas { | mayoría de la gente } irán junto con sus puntos de vista sobre este sitio web { | este sitio | este sitio web} . | { Hola | Hola | Hola | ¿Qué hay de nuevo } , { que iniciar sesión en | cheque | read } { su nuevo material | blogs | Blog } { periódicamente | como cada semana | diario | periódicamente } . Su { cuentos | escribir | humorístico } { estilo es increíble | ingenioso } , { mantener haciendo lo que estás haciendo | el buen trabajo | it up} ! | Yo simplemente { | } { solo no podía | no podía dejar } { | salir | desaparecerá } { su sitio | Página web | sitio web} { antes | } antes que sugiere que realmente { | muy | } { realidad disfruté | amado } { el estándar | la costumbre } { información | info} { una persona | an} { suministro individual | proporcionará } { para su | en el | en el | a sus visitantes } { | } huéspedes ? Es { va a | a } ser { atrás | nuevo } { frecuentes | regular | cesar | constante | cesar | frecuencia | continuamente } { para | a } { comprobar | visita | examinar | investigue verificación cruzada } mensajes nuevos | { Quería | Necesitaba | Quiero | Necesito } para darle las gracias por este gran { | excelente | fantástica | maravilloso | bueno | muy buena } ver ! I { Definitivamente | Ciertamente | absolutamente } { disfrutado | Querida } { cada poco de | } poco de ella. { Tengo | Tengo | Tengo } que { marcado | marcado libro | libro marcado | guardado como favorito } { de revisar | para mirar } { nuevas cosas que | cosas que } post … | { Hola | Hola | Hola | ¿Qué hay de nuevo } , sólo quería mencionar { | decir | dirá } i { disfrutado | querido | amado } { este artículo | Poste | blog } . Fue inspirador { | divertido | práctica | servicial } . Sigue publicar! | I { { dejará | caída | { escribir | crear } } a { un comentario | dejar una respuesta } | { drop un comentario | dejar una respuesta } | { comentario | dejar una respuesta } } { cada vez | cuando | siempre } I { apreciarán | como | disfrutarán especialmente de } a { post | article} en un sitio de { | { blogs | website } | página | Página web } o { tengo | si tengo algo } a { add | contribuir | valioso que aportar } { a la discusión | a la conversación } . { Es | Por lo general es | Por lo general es | es } { resultado de | provocada por | causada por } el { pasión | fuego | sincerness } { comunicados | mostrado } en { post | article} I { leer | mirado | navegado } . Y {on | después } { este post | article} % blog_titulo %. I { { fue | fue realmente movido } | { fue | era realmente emocionada } } { suficiente para caer | { dejará | caída | { escribir | crear } } | Poste } a { pensamiento | Comentar { | { comentario | dejar un comentario } una respuesta } } { | | | | } i { Qué tienen en realidad tienen | } { { | a unas pocas preguntas } | un par de preguntas | 2 preguntas } para usted { si { qué no | no | no suelen | no suelen } cuenta | si es { allright | okay } } . { Es | ¿Será } { sólo | | Sólo simplemente me } o { do | lo hace parecer { | aparecer | dar la impresión | buscar | mirar como si | se parecen como } } { algunas | algunos } de { los | { estas } comentarios | respuestas | comentarios } { ven | aparecer | encontrado } { como son | como si fueran | Te } { procedente de | Escrito por | dejada por } { cerebrales muertas personas | visitantes | gente | personas } ? Y , si usted es { publicar | escritura } {on | at} { otro | adicionales } { Webs | sitios sociales sitios en línea | | Los sitios sociales en línea | Personas } , { Me | Me gusta } { seguimiento | mantenerse al día con usted } { | { nada | todo } { nuevo | frescas } tienes que publicar } . Podría { | } Ojalá que {list | hacer una lista } { todo | todos | las URL completa } de { el | todos los } { sociales | comunales | Comunidad | público | compartidos } { páginas | Sitios } como su { Twitter alimentación , la página de Facebook o LinkedIn profile | linkedin perfil , la página de Facebook o Twitter feed | página de Facebook , Twitter feed , perfil o linkedin } ? | { Hola | Hola } , me gusta leer { todos | por } el {article | Poste | Poste article} . I { gusta | wanted } para escribir un pequeño comentario para apoyarte. | I { siempre | continuamente | } cada vez que pasamos mi media hora para leer este { blogs | blog | página | Página web | sitio web} ‘ s { Artículos | mensajes | artículos o reseñas | contenido } { días | diario | diario | todo el tiempo } junto con una taza de { | } taza de café. | Yo siempre { | para siempre | todo el tiempo | constante | } por correo electrónico cada vez que este { blogs | blog | página | Página web | sitio web} página de entrada a todos mis amigos: { | asociados | contactos } , { porque | desde | como | por la razón que } si como para leerlo y luego { | después | Siguiente | luego } { mis amigos | links | contactos } también lo hará. | Mi { codificador | Programador | desarrollador } está tratando de persuadir a { | } convencer . Me mude a la red de PHP. Siempre me ha disgustado la idea debido a los gastos | Gastos { } . Pero ha tryiong no obstante. He estado usando { movible de tipo | WordPress } de { varios | varios | numerosas | varios | } varias páginas web desde hace un año y am { nervioso | ansiedad | preocupada | } interesados en cambiar a otra plataforma. He oído { fantástica | Muy bueno | excelente | gran | } buenas cosas sobre blogengine.net . ¿Hay alguna manera de transferir { | } importación toda mi wordpress {content | Mensajes } en ella ? { Cualquier tipo de | } Cualquier ayuda sería muy { | } grandemente apreciada! | { Hola | Hola | Hola | Hola | Hola | Buen día !} Podría jurar que he estado en { | } { visitado este blog | Este sitio web | este sitio | este sitio | tu blog } antes, pero después de navegar a través de { | atravesando | viendo } { algunos de los | algunos del | muchos de los mensajes } { | artículos } me di cuenta de que es nuevo para mí. { De todas formas | De todos modos | Sin embargo | Independientemente } , estoy definitivamente { | } { ciertamente feliz | contento | encantados } { Encontré | descubrí | parecí | me topé } y estaré { bookmarking | Revista -marking } y revise de nuevo { frecuentes | regular | menudo } ! | { Terrific | Gran | Wonderful } {article | obra } ! { Es | Es } { el tipo de | la clase de } { información | info} { que están destinados a | que se supone que | que debe ser compartida { } alrededor de la | } { a través de la web | Internet | net } . { Disgrace | Vergüenza } en { la { buscar | búsqueda } motores | Google } de { ahora no | no | no } { posicionamiento este post | enviar | publicar | soportar } { superior | altos } ! Vamos, una y { discutir con | discutir con | buscar consejo de | Visita | consultar con mi } { sitio | sitio web | website } . { Gracias | Gracias } =) | { Heya estoy | i am } por primera vez aquí . Me encontré con { | } encontrado este foro y me parece verdaderamente { | } realmente útil y que me ayudó mucho { | mucho } . Espero poder dar algo a cambio y ayudar a { | ayuda } otros como tú ayudaste { | } asistido mí. | { Hola | Hola | Hola | Hola | Hola | Saludos } , { pienso | Yo creo | que hago creer | que hago pensar en | No hay duda de que } { su sitio | Web | sitio web | tu blog } { pudo ser | puede ser | | podría ser posiblemente podrían ser } con { navegador | navegador Internet | navegador de web} { compatibilidad cuestiones | problemas } . { Cuando | Cada vez que } { miren tu | eche un vistazo a su página web } { | sitio web | sitio | Blog } en Safari, que se ve muy bien pero cuando { | Sin embargo , cuando | Sin embargo , si | no obstante, cuando la apertura } { en Internet Explorer | IE | IE} , { tiene | } que tiene algunos asuntos que se superponen . { Acabo | simplemente | Simplemente } { quería darle a | a dar con una } cabezas rápidos para arriba! { Aparte de eso | Aparte de eso | Además de eso | Aparte de eso } , { fantástica | maravilloso | excelente | } { excelentes blogs | sitio web | site} ! | { Una persona | Alguien | Alguien } { necesariamente | esencialmente } { echar una mano | ayuda | asistencia para que { } serio | críticamente | considerablemente | severamente } { artículos | Mensajes } { quisiera | I might | Yo había estado } . { Es | Es } de { primero | primera vez que frecuentaba } { su página web | página web } y { a este punto | medida | hasta el momento | Hasta ahora } ? I { asombrados | sorprendió } con el { investigaciones | analisis } que hizo al crear { | } { hacer este real | Este particular } { post | enviar | publicar | soportar } { increíble | increíble | extraordinaria } . { Great | Wonderful | Fantástico | Magnificent | Excelente } { Tarea | Proceso | Actividad | trabajo } ! | { Heya estoy | i am } para { el primario | la primera } tiempo aquí. Me encontré con { | } encontrado este foro y yo { en la búsqueda | buscar | encontrar { } Es verdad | realidad } { útiles | servicial } y que me ayudó mucho { | mucho } . { Espero | Espero | Espero } { darle | ofrecer | para proveer | presentar algo } { | algo } { atrás | nuevo } y { ayuda | ayuda } { demás como tú | como usted} { ayudado | asistido } mí. | { Hola | Hola | Hola | Hola | Hola | Buen día | Hola } ! { Acabo | Simplemente } { gustaría | quiere | deseen } { darle a | ofrecerle unas enormes } { } | big thumbs up { el | para su gran } { | } { excelente info | Información } { tienes | tienes | tienes aquí } { | } aquí en este blog . { Seré | Estaré | Soy } { volviendo a | volver a } { tu blog | sitio | Web | su sitio web} más pronto. | I { Siempre | todo el tiempo | } cada vez que se utiliza para leer { | } {article estudio | Poste | pieza de escritura | punto } en periódicos , pero ahora ya soy un usuario de { internet | web | net } {so | por lo tanto | por lo tanto, } a partir de ahora estoy usando neto { artículos | mensajes | artículos o reseñas | Contenido } , gracias a la web. | Su forma { | Método | medios | Modo } de { describiendo | explicando | diciéndole } { todo | todo | todo } en este {article | Poste | pieza de escritura | punto } { es realmente | realidad | hecho | verdaderamente | genuinamente } { Niza | agradable | bueno | fastidioso } , { todo | { } cada uno puede | poder | ser capaces de } { fácilmente | sin dificultad | esfuerzo | sencillamente } { comprender | saber | conocer } es , muchas gracias . | { Hola | Hola } no , { Encontré | descubrí } el { blogs | sitio web | sitio web | site} { mediante | mediante | por el uso de | a través de Google { } , al mismo tiempo que | mientras | aun as | while} { búsqueda | Búsqueda de } a { similares | comparable | relacionado } { tema | materia | subject} , { su sitio | sitio web | Página web } { conseguido aquí | } llegó arriba, se ve { | aparece | parece | parece ser | parece ser como una buena } { | gran } . { Tengo | Tengo } marcado en mis favoritos de google . { Hola | Hola } allí, simplemente { | } { acaba convertido en | convirtieron | se | sea | transformado en } { consciente de | Alerta a } el { blogs | weblog } { thru | por | mediante Google } , { y encontró | y ubicado } que { es | es } { muy | } verdaderamente informativo. { Soy | Soy } { gonna | ir a } { cuidado | cuidado } de bruselas . { Haré | Voy } { aprecio | agradecería } {if you | debe usted | cuando | en caso de que | en caso de que | a los que | si le toca } { continúas | Progresar } { en este futuro } . { Mucha | Mucha | Muchos | Numerosos } { otras personas | gente | otras personas | personas } { seré | será | puede ser | probablemente será | puede | probablemente se } { beneficiado de su | Salida de su escritura } . ¡Salud! | { Soy | Soy } curiosidad por saber lo que el blog { sistema | Plataforma } { usted ha estado | que resultan ser | es | eres } { trabajar con | utilización | usando } ? Estoy experimentando { | } tiene algún { menores | small} { problemas de seguridad | Ediciones } con mi último { página | Página web | Blog } y { lo haría | Me } gustaría encontrar algo más seguro { | libre de riesgo | salvaguardado | seguro } . ¿Tiene algún { soluciones | Sugerencias | Recomendaciones } ? | { Soy | Soy } { muy | } muy impresionado con sus habilidades de escritura y también { | } , así como con el diseño de su { blogs | weblog } . Es este un tema de pago o que te { personalizar | modify } usted mismo? { De cualquier manera | De todos modos } { mantener el buen | } excelente calidad de la escritura , {es | es } raro ver a un buen { | gran } blog como éste { estos días | actualidad | Hoy } . | { Soy | Soy } { extremadamente | verdad } { inspirada | } { impresionado con su | junto con su | junto con su escritura } { talentos | | habilidades habilidades } { y también | elegantemente como { | y | prolijamente } como { } con el diseño | formato | Estructura } { para su | en el | en el | a su } { blogs | weblog } . { Es esto | ¿Es que esto } a pagar {subject | tema | tema | motivo } o tuvo personalizar { | } modify que { usted mismo | su auto } ? { De cualquier manera | De todos modos } { quedarse | mantienen } el | { calidad | calidad alta } { bonita excelente } escritura, {es | es } { raras | infrecuente } { de archivos | A ver | a mirar } a { bonita | gran } { blogs | weblog } como este { estos días | actualidad | } .. hoy | { Hola | Hola } , después de Neat . { No | No } { un problema | una edición } { con su | junto con su | junto con su } { sitio | sitio web | website } en { a Internet | web} explorer , { mayo | fuerza | podían | haría } {Compruebe | test } esto? IE sigue { | } sin embargo, es el mercado de { | } { líder de mercado | jefe } y { un gran | un buen | gran | a gran parte de } { | sección | componente | Parte de | componente | elemento de } { otras personas | gente | otras personas | personas } { se dejan fuera | omita | Señorita | pase } { su gran | maravilloso | fantástica | magnífico | excelente escritura } { debida a | } debido a este problema. | { Soy | Soy } no sé donde estás { | } que está recibiendo su { info | Información } , { pero bueno | gran } tema. Me tiene que pasar algún tiempo de aprendizaje { más | mucho más } o comprensión más . Gracias por un gran { | maravilloso | fantástica | magnífico | excelentes } { información | info} que estaba buscando esta información { | info} para mi misión . | { Hola | Hola } , creo que vi que visitó mi { blogs | weblog | Página web | sitio web | site} {so | lo } que llegué a ” devolver el favor ” { soy | Soy } . { Intentar a | } intentar encontrar cosas para mejorar { | { mejorar } mi sitio web | sitio | sitio web} Supongo que su autorización para utilizar algunas de { | ! } algunas de sus ideas! ! | { Hola | Hola } , { i creo | que siento | creo que i } { sierra | notado } que visitó mi { blogs | weblog | Página web | sitio web | site} {so | Así } i { conseguido aquí | vino } a { volver | volver } de { preferiría | escoger | favor | quiere | deseo } { soy | estoy ?} . { intentando | intentar } { en la búsqueda | Encuentra | para encontrar cosas } { | } cuestiones para mejorar { | { mejorar } mi sitio web | sitio | sitio web} { supongo | asumo | Supongo } ! su { suficientemente bueno | ok | { } adecuada para usar | hacer uso de algunas de } { | a pocos { } de sus Ideas | Conceptos | Ideas } ! ! | { Hola | Hola } allí, se convirtió { cuenta | Alerta a } su blog a través de Google , y se encontró que { es | es } { muy | } verdaderamente informativo. { Soy | Soy gonna } { | } va a mirar hacia fuera para Bruselas . { Haré | Voy } { aprecio | agradecería } si continúa esta { } en el futuro . { Mucha | Mucha Mucha | | } Numerosas personas se beneficiaron de su escritura. ¡Salud! | { Soy | Soy } { ahora no | no | no } { Seguro | positivo | cierta } { en | el lugar } { usted es | que está recibiendo su { } info | Información } , { embargo | pero } { bueno | } gran tema. I { necesita | } debe pasar un tiempo { | } { tiempo estudiando | aprendizaje | averiguar } { más | mucho más } o { elaboración | conocimiento | averiguar } más . { Gracias | Gracias } de { grande | maravilloso | fantástica | magnífico | excelentes } { información | info} { Yo solía ser | Estaba } { buscando | en busca de | a la caza de | búsqueda de } la { información | info} para mi misión . | { Hola | Hola } { familiar | querido | } amigo mío! Yo quiero { | } desear decir que este {article | Poste } es { impresionante | asombrosa } , { grande | } agradable escrito y { vienen con | Incluye } { casi | aproximadamente } { todos importantes | | vitales significativas } infos . { Estaría | Me gustaría } { de archivos | A ver | buscar } { más | extra } posts como este. | { hi | hola } , {I love | me gusta | Me gusta !} { su escritura para | } { muy mucho | mucho | mucho } ! { porcentaje | proporción | Compartir } { es mantenerse en contacto | mantener una correspondencia | comunicación | estar en contacto} { más | extra } { aproximado | sobre } la { post | artículo } en AOL? I { necesitar | requerirá } { un experto | especialista } { en este | en este espacio } { | Área | casa } { resolver | desentrañar | } para resolver mi problema . { Puede ser | Quizás } { es | es } que usted! { Echando un vistazo | Trabajo | Tener un vistazo } { adelante | } { delante de archivos | A ver | a mirar } usted. | { Soy | Soy } { realmente amar | } disfrutando el tema / diseño de su sitio de { | blog | sitio web | sitio web | Blog } . ¿Alguna vez te encuentras con cualquier navegador web { | explorador | explorador } { problemas de compatibilidad | Ediciones } ? A { número de | puñado de | dos | número reducido de | algunos de mis blogs { } audiencia | Visitas | } lectores se han quejado acerca de mi { blogs | sitio web | sitio } No { operativo | Trabajando } correctamente en Explorer, pero se ve muy bien in { Safari | Chrome | Opera | Firefox } . ¿Tiene algún { soluciones | Ideas | consejos | consejos | Sugerencias | } recomendaciones para ayudar a solucionar este problema { | } problema ? | { Bueno | Gran | Muy buena } { info | Información } . Lucky me encontré { | descubrí | parecí | Me encontré con | Hace poco encontré } { su sitio web | sitio | tu blog por casualidad } { | } por casualidad ( stumbleupon ) . { Tengo | Tengo } { marcada it | salvó | Revista marcaba | libro marcado it | guardado como favorito } para más tarde! | Es { grande | gran | impresionante | maravilloso | fantástica } que vas a encontrar { Ideas | pensamientos } de {article | Poste | pieza de escritura | punto } , así como de nuestro { discusión | discusión | Diálogo } hecho { aquí | en este lugar | en este momento } . | Si deseas { | deseo | desear | quisiera } a { aumentará | mejorar | creciendo } { su experiencia | conocimiento | conocimiento | know how } { | Sólo simplemente | Recién } sigan visitando este {website | sitio web | sitio | Página web} y se actualizará con la {latest | Novedades | Más reciente | más actualizada al día | más caliente } { noticias | información | cotilleos | news update} publicado aquí. | ¿Qué está { Teniendo lugar | Happening | Bajando } { soy | i am } nuevo en esto, me encontré con este { Tengo | Tengo } { encontrado | descubierto } No { positivamente | absolutamente } { útiles | Útil } y ha ayudado a { | } me ayudó a chorros . { Espero | Espero | Espero } a { dar una contribución | COLABORA } { otro | diferente } { usuarios } | clientes como su { ayudado | asistido } mí. { Bueno | Gran } trabajo. | { Wow | Hurra } , que es lo que estaba buscando { | buscar | búsqueda | } para explorar , qué cosas { | Información | Datos | Material } ! { presentará | } existente aquí en este { blogs | blog | página | Página web | sitio web} , gracias administración de este {website | sitio web | página | Página web} . | Si deseas { | deseo | desear | quisiera } para { llevar | conseguir | obtener } { mucho | mucho | mucho } de { este artículo | Poste | pieza de escritura | punto } Entonces usted tiene que solicitar { tales | estos | } { estrategias técnicas | Métodos } a su ganado { blogs | blog | página | Página web | sitio web} . | Es una { awesome | destacable | sorprendente } {article | Poste | pieza de escritura | punto } {for | diseñado por | a favor del | en apoyo a } todos los { Internet | web | línea } { usuarios | personas | televidentes | visitantes } , . se llevará { | conseguir | obtener } { beneficiarse | } ventaja de ello estoy seguro | { Que he | Tengo } { leer | Aprender } { algunos | varios | algunas } { justo | bueno | excelente } cosas aquí . { Definitivamente | Ciertamente } { pena | Valor | price} marcadores para volver a visitar .
Como podéis apreciar, es un archivo que escogiendo segmentos y subsegmentos aleatorios permite crear diferentes frases, tales como:
- Que he leer algunas cosas aquí.
- Tengo aprender varias excelentes cosas aquí.
- Que he aprender varios bueno cosas aquí.
Tiene cierta ingeligencia en cuanto que hay algunos componentes que son opcionales, otros multiopción, etc. Por suerte de momento y gracias en gran parte a las tiempos verbales, los verbos irregulares, los pronombres y todas las normativas que en general odiábamos de estudiantes, el resultado es bastante malo, de modo que a simple vista, podemos detectarlos fácilmente. En inglés debería ser mucho más fácil, y creo que es así, por eso tanto spam irrelevante en esa lengua.
Calibre portable x64
El gestor de ebooks Calibre, está disponible para multitud de plataformas Linux, OS/X, Windows 32 bits, Windows 64 bits, … Incluso hay una versión portable para Windows que no requiere instalación. Lamentablemente nunca han distribuido una versión portable de 64 bit para Windows.
En este artículo os voy a explicar como la podéis hacer vosotros mismos, un proceso que es tremendamente sencillo.
Lo primero que necesitamos es una versión portable de 32 bits, extraída en nuestro equipo, y funcionando. Si no la tienes, lo primero es que la descargues.
Una vez la tengas, verás que en la ubicación donde está alojada, hay 3 carpetas: Calibre Library (con nuestra biblioteca de libros); Calibre Settings (con las preferencias del programa); y Calibre (con el propio programa). Bien, ahora nos hacemos con la versión normal, no portable, para Windows 64 bits desde aquí. Es un instalador MSI, así que la forma más sencilla de hacernos con su contenido es instalarlo. Para evitar conflictos es importante escoger una ubicación de destino diferente a donde tengamos la edición portable.
Ya instalado, procedemos a copiar todos los archivos que se han instalado, y los colocamos dentro de la carpeta Calibre de nuestra versión portable, sobreescribiendo todos los archivos que ya existan. Procedemos a desinstalar la versión normal, y verificamos que la portable funciona correctamente. Para ello lanzamos calibre-portable.exe, y esperamos a que el programa se abra.
Si todo ha ido bien, podemos proceder a abrir el Administrador de tareas y comprobar que efectivamente Calibre.exe es ya un proceso de 64 bits.
Como aseguraba al principio, un proceso rápido y sencillo. Lo siguiente que quedará será cada vez que queramos actualizar el programa, repetir la segunda parte del proceso. Es decir, hacernos siempre con la versión normal de 64 bits, y sobreescribir sus contenidos sobre la portable o la normal que tengamos en el caso que ya hayamos hecho la mezcla.
Quiero aprovechar para comentaros también que debido a limitaciones en el propio Calibre, las rutas donde lo instalemos o extraigamos, están limitadas a un máximo de 90 caracteres en ANSI, es decir, sin caracteres extendidos. Este problema ocurre tanto en las versiones de 32 como de 64 bits, ya sean portables o instalables.
Parece que los desarrolladores lo atribuyen a una limitación de Windows, que es del todo falsa, pues Windows soporta perfectamente carpetas unicode, y en el peor de los casos MAX_PATH está definido a 256 caracteres. De nuevo el arreglo es sencillo. Se trata de lanzar desde el nombre corto del directorio donde lo tengamos el calibre-portable.exe. Lo más conveniente es un archivo BAT, que en mi caso es este:
CalibreRun.bat:
@echo off rem Fixed max 90 characters path set calibre=\users\javier~1\archiv~1\calibre path=%calibre%;%calibre%\calibre\;%path% cd %calibre% start calibre-portable.exe |
Lo único que tendrás que modficar es la linea de set calibre, con la ruta donde lo tengas instalado/extraído. Pero recuerda que esta ruta debe ser en nombres cortos 8:3, así que usa DIR /X para saber la equivalencia, o alguna utilidad de terceros.
A partir de ahí lanza CalibreRUn.bat o como lo hayas llamado, en vez de calibre-portable.exe, y ya tendrás Calibre funcionando en la carpeta que tu quieres, independientemente de que tenga una ruta muy larga o el nombre tenga acentos, espacios, u otro carácter especial.
¿Cómo transformar PDF CMYK a RGB con FileOptimizer?
Una utilidad colateral que ha surgido en FileOptimizer, es la conversión rápida y sencilla de documentos PDF con codificación de color CMYK a RGB.
La codificación CMYK, utiliza cuatro canales de color (Cyan, Magenta, Amarillo y Negro), en contraposición a los 3 de RGB (Rojo, Verde y Azul). Por un lado esta diferencia, ocasiona que los documentos en CMYK sean del orden de 33% más pesados, pero además, y por motivos de simplificación del código, es probable que se vean incorrectamente en determinados visualizadores de PDF, particularmente en dispositivos móviles, ya estén basados en iOS o Android.
CMYK tiene sentido cuando hablamos de impresión profesional en formato papel a 4 tintas, donde no será necesario realizar ninguna conversión. Sin embargo, si hablamos de digital, tanto en ordenadores personales, como en dispositivos móviles o web, lo adecuado es RGB.
Dentro de la multitud de formatos soportados por FileOptimizer (BMP, DIB, DLL, BPL, DRV, LZL, SYS, CHM, CHS, CHW, DOC, DOT, FPX, MDB, MDT, MIX, MPD, MPP, MPT, MSI, MSP, MST, ONE, OST, PPS, PPT, PUB, PUZ STICKYNOTES, SNT THUMBS, DB, VSD, VST, VSS, XL, XLC, XLM, XLS, XLW, XSF, XSN, EXE, SCR, GIF, GZ, TGZ, SVGZ, JNG, JPG, JPEG, MNG, MP3, OBJ, O, LIB, A, OGG, OGV, EPDF, PDF, APNG, ICO, PNG, SWF, FAX, TIF, TIFF, PTIF, PTIFF, WEBP, AIR, APK, APPX, CBZ, DOCM, DOCX, DOTX, DOTM, DWFX, EPUB, IPA, JAR, MPP, ODT, OXPS, PPAM, POTM, POTX, PPSM, PPSX, PPTM, PPTX, PUB, SLDM, SLDX, VDX, VTX, VSX, XAP, XLAM, XLSM, XLSX, XLTM, XLTX, XPS, ZIP, AAI, AVS, DCX, PCC, PCX, FITS, JP2, JPC, HDR, HRZ, MIF, MIFF, MTV, OTB, P7, PALM, PDB, PBM, PCD, PCDS, PFM, PGM, PICON, PIC, PICT, PNM, PPM, PSB, PSD, SUN, VICAR, VIFF, WBMP, XBM, XPM, XWD, …) se encuentra por supesto PDF gracias al plugin incorporado de Ghostcript, automáticamente se convierten los documentos de origen de CMYK a RGB, en el caso que usaran ese formato.
Si ya eran RGB, los mantendrá en ese formato, pero aplicando las optimizaciones de linearización, y opcionalmente de downsampling de imágenes, con el objetivo de reducir su tamaño manteniendo la calidad original (sin pérdidas), de manera que es suficiente con arrastrarlos a FileOptimizer no solamente para reducir su peso, sino también para mejorar su compatibilidad.
Avira 14 y Avast 2014
Pese a que me gusta el campo de la seguridad, y de los antivirus en particular, salvando algunas excepciones, no hablo demasiado de ellos aquí.
La razón es que cada nueva versión, tras nuevas técnicas de mercadotecnia, nuevas interfaces de usuario, etc, pero pocas veces llegan con novedades tecnológicas importantes.
En el caso de Avast 2014, si que se ha revisado el motor de análisis, que ahora es mucho más veloz, tanto para archivos ejecutables como de texto. No puedo más que halagar el esfuerzo que han puesto al conseguirlo renovar por fuera, y también por dentro.
Avira 14, se queda algo corto. Externamente es casi igual que la versión 2013, aunque internamente se han efectuado algunos cambios para permitirle añadir nuevas funciones poco a poco, y sin tener que esperar a la versión 15. Algo parecido a lo que tenían con la 8.0, 8.1 y 8.2. Lo primero que tienen pensado para él, es la actualización al nuevo motor 8.3, que sobre el actual 8.2 carga más rápido las firmas, y es más fácil de ampliar. Lo segundo será el análisis vía nube.
Son ambos productos gratuitos, que además superan ampliamente a la mayoría de sus competidores, tanto comerciales, como gratis. No me malinterpretéis aquí, no afirmo que sean los mejores, o que sean superiores a algunos productos concretos de pago, solamente que están muy bien, y son gratuitos.
Avira 14, se caracteriza desde hace años por un magnífico motor. Ofrece excelentes ratios de detección, es rápido analizando, consume poca memoria, y se actualiza con regularidad. Sin embargo, tanto a nivel de interfaz de usuario, como de funciones, es bastante rudimientario.
Avast 2014 (9.0) sería casi lo opuesto. Un interfaz de usuario atractivo y ágil, muchas funciones adicionales incluso en la versión gratuita, un sistema de actualizaciones tremendamente eficaz, etc. Pese a ello, su motor es bastante inferior al de Avira. Cierto que el consumo de memoria sigue siendo similar o incluso inferior, pero si hablamos de velocidad de análisis, y sobre todo de grado de detección, le va a la zaga.
Vemos que aunque individualmente son muy buenos, lo que le suele faltar a uno, lo tiene el otro y a la inversa. Estoy convencido que si alguien pudiera combinar ambos, estaríamos ante el mejor antivirus del mercado, independientemente que fuera gratuito o de pago. Ese es el motivo que me lleva a ir cambiando de uno a otro con cierta regularidad. Son muy buenos, en efecto. Pero con carencias que ninguno de los dos ha sabido hasta el momento solucionar.
Declive de Delphi
Pese a que Pascal nunca fue santo de mi devoción, debo reconocer la extraordinaria contribución que ha éste ha realizado al mundo del desarrollo.
En 1995, con Delphi 1.0, el ecosistema de herramientas de programación para Windows era bastante limitado: Visual C++ 2.0, Borland C++ 4, Watcom C++ 10, y Visual Basic 3. Había una gran dualidad entre ellas, y es que si se buscaba el rendimiento, las primeras eras las más adecuadas, mientras que si se buscaba la productividad, sólo VB era adecuado.
Delphi lo cambió todo, con una herramienta de desarrollo rápido (RAD), muy similar en características a y filosofía a Visual Basic, pero con la capacidad de generar código nativo en vez de p-code, y enlazar estáticamente con sus librerías.
Estaba basado en toda la experiencia adquirida con Turbo/Borland Pascal, un lenguaje maduro, potente, un compilador rapidísimo, y una calidad de código generado bastante buena.
Por fin podíamos generar aplicaciones de 16 bits para Windows 3.x, que estaban cercanas a la eficiencia de C/C++, y al mismo tiempo eran relativamente sencillas de programar.
Con el lanzamiento de Visual Basic 4, que podía generar p-code de 32 bits, Borland respondería un año más tarde con Delphi 2, capaz de generar código nativo de 32 bits.
En 1995, Microsoft actualizaba su Visual Basic, a la popularísima versión 5, que era capaz de generar código nativo, pero no de enlazar estáticamente con los runtimes. Se mejoraba su soporte de objetos, pero seguía siendo en ese sentido solamente basado en objetos, una tecnología inferior a la que ya tuviera Delphi 1, totalmente POO.
Visual Basic se había dormido en los laureles, y hasta 1998 no se presentó la versión 6, mientras que por su lado, Borland siguió trabajando en Delphi: Delphi 3 (1997), Delphi 4 (1998). Lo que es más importante es que VB 6, representó la última versión del entorno de programación, que luego sería relevado por VB.NET en 2002, y al que muchos desarrolladores fueron reticentes a migrar. De modo que el éxito de Delphi, continuaría: Delphi 5 (1999), Delphi 6 (2001) y Delphi 7 (2002).
Tras unos intentos no demasiado exitosos de soporte de Linux, Borland comete el primer error, intentar competir con Microsoft en su terreno: .NET, con Delphi 8 de 2003. Se rectifica en 2005 con Delphi 9, que soporta también Win32 además de .NET, pero ya es tarde, .NET se está extendiendo, y Lazarus 0.9 es ya bastante usable, gratuito y de código abierto.
En 2006, se empieza a hablar que están trabajando en un backend x64 para el compilador, algo que muchos desarrolladores están esperando. Se dice que estará listo en 2008, es decir, dos años después, y la gente espera pacientemente.
Entre tanto se suceden nuevas versiones, con más bien pocas mejoras: Delphi 2006 (10), Delphi 2007 (11), Delphi 2009 (12), Delphi 2010 (14), Delphi XE (2011).
Se hace el silencio, y en 2009, se dice que será en 2010 cuando habrá soporte x64, lo que serían 4 años depués de las primeras noticias. Muchos desarrolladores se van a Lazarus, que es ya usable. Christian Ghisler, decide portar su Total Commander, una tarea que le lleva varios meses, hasta que en 2012, presenta la versión 8.0, totalmente escrita en Lazarus, y con ediciones x86 y x64. Una prueba indiscutible de que Delphi ha perdido a sus seguidores.
Pasa el anunciado 2008, con nuevas versiones de Delphi, y se sigue sin tener soporte x64, cosa que no ocurre hasta XE2 de 2011. De nuevo una ristra de versiones, con más afán recaudatorio que novedades reales: Delphi XE2 (2011), Delphi XE3 (2012), Delphi XE4 (2013), Delphi XE5 (2013).
Poco después de su lanzamiento Ritlabs, anuncia una nueva versión de The Bat!, también con edición de 64 bits, y también gracias a Lazarus.
El resto de aplicaciones relevantes escritas en Delphi, o bien han desaparecido (FeedDemon, Skype, Ares, …), han abandonado Delphi (X1 Professional Search), no han actualizado la versión de Delphi (TOAD, UltraSearch, Website Watcher, …), o si lo han hecho, no ha sido para agregar soporte x64 (AIDA64, HeidiSQL, PowerArchiver, …).
En Embarcadero, parecen más centrados en intentar que Delphi pueda ser una herramienta de desarrollo válida para otras plataformas iOS, Android, OS X, cosa que consiguen de manera bastante antinatural. Mientras tanto, y por desgracia, las aplicaciones de escritorio que usan Delphi se reducen al mismo ritmo que lo hace su comunidad de desarrolladores.
Te sorprenderías de saber la cantidad de proyectos que siguen con Delphi 4, 5 6 y 7 sin actualizarse debido a falta de mejoras reales en la herramientas.
Las consecuencias son sin duda poco halagueñas. Nos quedaremos sin una brillante herramienta RAD, y derivado de ello, sin mi estimado C++ Builder, la úncia herramienta disponible desde hace años en combinar RAD con C++.
Paralelizador automático de Visual C++ 2013
Si el otro día hablaba del declive de Delphi, hoy vamos a justo lo opuesto. Como C/C++ un lenguaje de programación del que en bastante ocasiones se ha pronosticado su final, sigue vigente, e incluso ganando cuota de mercado.
El reciente Visual C++ 2013, viene con mejoras sobre la versión 2012 en cuento a funciones C99, STL y mejoras de rendimiento. En cuanto a esto último, me ha llamado la atención el paralelizador automático, una característica ya disponible con la versión 2012, pero que había pasado por alto. Lo que si es nuevo, es que se incluya como opción de compilador en el propio IDE dentro de C/C++ / Generación de código / Habilitar generación de código paralelo.
Basta añadir la opción /Qpar, para que Visual C++ detecte bucles que pueden ser paralelizados entre diferentes cores, y genere el código adecuado para hacerlo.
Se nos ofrece un control añadido sobre la paralelización automatizada, que de forma parecida a OpenMP, nos permite indicar al compilador como queremos que se comporte en este sentido. Bien, no es quizás tan potente y flexible, pero si mucho más fácil de utilizar, e integrado en el entorno.
Le indica a Visual C++ que debería intentar el siguiente bucle en n cores/procesadores:
#pragma loop(hint_parallel(n)) |
Le indica a Visual C++ que no debería en absoluto paralelizar el siguiente bucle:
#pragma loop(no_vector) |
En combinacón con hint_paralel, le indica al compilador que en el siguiente bucle, puede ignorar la comprobación de dependencias al vectorizarlo:
#pragma loop(ivdep) |
Formato propietario DOCX
En una conversación de hace algunos días, me pedían unos documentos que estaban originalmente en formato DOCX, convertidos en algo así como un “formato no propietario”. Me resultó curioso, por lo que aprovecharé este espacio para aclarar algunos conceptos.
Empezamos por lo que es DOCX, el formato de documentos con el que guarda por defecto Word 2007 y posteriores, en contraposición a DOC, que era el tipo por defecto para Microsoft Word desde la versión 1.0 de 1983, y que sufrió diferentes revisiones a lo largo del tiempo, a pesar de conservar la misma extensión.
¿Qué es un formato propietario?, pues Wikipedia lo define muy bien: Un formato propietario o cerrado es un formato de archivo protegido por una patente o derechos de autor. Tales restricciones típicamente intentan prevenir la ingeniería inversa; si bien la ingeniería inversa en los formatos de archivo con propósitos de interoperabilidad generalmente es legal, según la creencia de quienes la practican. Las posiciones legales difieren conforme al país, entre otras cosas, en lo que se refiere a las patentes de software.
Sin embargo, DOCX, al pertenecer a la famila de formatos de Office Open XML, es en realidad un formato abierto. Es decir, su definición, diseño, estructura y capacidades están documentadas, y puede ser usado por terceros sin restricciones legales. Ello permite que desarrolladores ajenos a Microsoft como Softmaker con su Office, Apache con su OpenOffice, o LibreOffice, sean capaces de leer y escribir esos archivos.
El formato Office Open XML, no deja de ser un archivo ZIP, que contiene archivos XML, y esquemas, como podemos observar, todo muy abierto. Probablemente la confusión venga dada por el hecho que a pesar de ser abiertos en cuanto a especificaciones, lógicamente su implementación no lo es. Word es un software comercial, y además de código cerrado, pero eso no quita que en base a esas especificaciones públicas, pueda tratarse con el formato, que es en todo caso abierto.
Es un caso parecido a ZIP, o HTML, donde la especificación es abierta, pero la implementación original puede no serla.
Mejorar el rendimiento de SQLite
Con el desarrollo de SQLite 4, el énfasis se está poniendo fundamentalmente en mejorar su rendimiento. Es una consecuencia lógica debida a su mayor popularidad, que la han hecho evolucionar como backend de datos de aplicaciones cada vez más complejas.
Hasta ahora, los esfuerzos se destinaban sobre todo a añadir nuevas funcionalidades, al mismo tiempo que mantenían el código lo suficientemente compacto, como para correr en plataformas con recursos hardware limitados.
En este sentido, algunas opciones de compilación nos permiten añadir funciones que por defecto no están activas tales como SQLITE_ENABLE_FTS4, SQLITE_ENABLE_RTREE o SQLITE_ENABLE_STAT4; mientras que otras, nos dan la oportunidad de mejorar su rendimiento: SQLITE_TEMP_STORE 2, SQLITE_THREADSAFE 2 y SQLITE_ENABLE_ATOMIC_WRITE.
Sin embargo es habitual que trabajemos con versiones precompiladas de SQLite, ya sea desde WebSQL, sobre las que no tenemos control en cuando a compilación. Para ello, el sistema nos ofrece ciertos PRAGMA, que permitirán ajustar su comportamiento en tiempo de ejecución, y así, mejorar su velocidad de ejecución.
Es interesante comprobar:
- PRAGMA journal_mode=MEMORY;
- PRAGMA journal_mode=OFF;
- PRAGMA synchronous=OFF;
Por supuesto, como buena constumbre, forzar el purgado, el reanálisis, y el reindizado cada vez que abrimos la base de datos, o preferiblemente cada vez que la cerremos, evitará que las prestaciones se degraden a medida que haya movimiento de datos. Os podéis dirigir a:
- VACUUM;
- ANALYZE;
- REINDEX;
Marcas alemanas ciberpunk
Con una floreciente industria e ingeniería alemana, con empresas como Porsche, BMW, Volkswgen/Audi, Mercedes Benz, Maybach, Opel, MAN, Setra, Continental, Mobil 1, Staedtler, Rotring, Faber-Castell, Lamy, Liebherr, Krups, Sinn, Steingraeber & Söhne etc, no es de extrañar que William Gibson, y otros autores del género ciberpunk, pronosticaran allá por los años 80, que el futuro pasaría indudablemente por grandes multinacionales del sector tecnológico procedentes de Alemania.
Una conclusión que apoyada por conocidísimas marcas del gran consumo tales como Adidas, Puma, Bayer/Schering, Deutsche Bank, Granini, Haribo, Henkel, Knorr, Playmobil, Lufthansa, Aldi, Lidl, parecía tener mucha lógica.
Sin embargo, era difícil vaticinar que ni Alemania, ni Estados Unidos, ni siquiera Japón, se llevarían el gato al agua, ante la actual amenaza de China, India, Corea, …
De modo que la mayoría de tecnología alemana, es en el mejor de los casos una sombra de lo que se anticipaba. Y en el peor escenario, apenas un rastro visible. Me refiero a nombres como
Braun, Telefunken, Grundig, Loewe, AEG (propiedad de la holandesa Electrolux), Bosch, Blaupunkt, Leica, Miele, Rowenta, Whirlpool, BASF, Osram, Siemens/Nixdorf, Gigaset, Simyo, Saunier Duval, …
Incluso otros que llegaron a extinguirse, me refiero a Saba (propiedad de la francesa Thomson), …
Lo mismo podríamos aplicarlo en el resto de europa: Philips (Holanda), Thomson/Technicolor (Francia), Nokia (Finlandia), Ericsson (Suecia), …