Tengo una aplicación de visor de mapas heredada que usa WinForms. Es sloooooow (La velocidad solía ser aceptable, pero Google Maps, Google Earth apareció y los usuarios se estropearon. Ahora estoy autorizado a hacerlo si es más rápido :)Descarga de transformaciones de coordenadas a la GPU
Después de hacer todas las mejoras de velocidad obvias (almacenamiento en caché, ejecución paralela, no dibujar lo que no necesita ser dibujado, etc.), mi profiler me muestra que el verdadero punto de asfixia son las transformaciones de coordenadas al convertir puntos del espacio-mapa al espacio-pantalla. Normalmente un código de conversión se ve así:
public Point MapToScreen(PointF input)
{
// Note that North is negative!
var result = new Point(
(int)((input.X - this.currentView.X) * this.Scale),
(int)((input.Y - this.currentView.Y) * this.Scale));
return result;
}
La implementación real es más complicado. Las latitudes/longitues se representan como enteros. Para evitar perder precisión, se multiplican por 2^20 (~ 1 millón). Así es como se representa una coordenada.
public struct Position
{
public const int PrecisionCompensationPower = 20;
public const int PrecisionCompensationScale = 1048576; // 2^20
public readonly int LatitudeInt; // North is negative!
public readonly int LongitudeInt;
}
Es importante que los posibles factores de escala también están obligados explícitamente a la potencia de 2. Esto nos permite reemplazar la multiplicación con un BitShift. Así que el verdadero algoritmo es el siguiente:
public Point MapToScreen(Position input)
{
Point result = new Point();
result.X = (input.LongitudeInt - this.UpperLeftPosition.LongitudeInt) >>
(Position.PrecisionCompensationPower - this.ZoomLevel);
result.Y = (input.LatitudeInt - this.UpperLeftPosition.LatitudeInt) >>
(Position.PrecisionCompensationPower - this.ZoomLevel);
return result;
}
(UpperLeftPosition representents la esquina superior izquierda de la pantalla en el espacio del mapa.) estoy pensando ahora en la descarga de este cálculo en la GPU. ¿Alguien puede mostrarme un ejemplo de cómo hacer eso?
Usamos .NET4.0, pero el código debería funcionar preferiblemente en Windows XP también. Además, las bibliotecas bajo GPL no podemos usar.
+1 para mostrar los límites teóricos. – user256890
Solo para poner los números en perspectiva, ¿cuál es la velocidad aproximada de una CPU promedio de 2 núcleos en FLOPs? – user256890
Depende de lo que llame un FLOP. Digamos que su CPU de 2 núcleos tiene una velocidad de reloj de 2 GHz, y un FLOP tarda 4 ciclos de reloj. Podría hacer 2 * 2/4 = 1 GFLOP. Esa es una estimación muy cruda. –