Optimizing a C# engine
-
Upload
javier-canton-ferrero -
Category
Technology
-
view
191 -
download
2
Transcript of Optimizing a C# engine
Javier Cantón Ferrero
@jcant0n
http://geeks.ms/blogs/jcanton/
Optimizando un motor de videojuegos en C#
Structs
• Objetos con una vida muy corta de tiempo
• Mejor cuando solo trabaja el Stack
• Tener en cuenta el GC
• Usar paso por referencia siempre que sea posible
Ejemplo
Matrix a, b, cc = Math.Multiply( a, b )
4 bytes / float16 floats / Matrix3 copias
3 * 16 * 4 = 192 bytes
Garbage Collector
• Salta cada vez que el heap crece en un determinado tamaño
4 bytes / float16 floats / Matrix3 copias
3 * 16 * 4 = 192 bytes
1MB = 1048576 bytes1048576 / 192 bytes = 5461,3
5461,3 / 60 fps = 91,02
private void UpdateMatrices(Matrix world0, Matrix view0, Matrix projection0,Matrix world1, Matrix view1, Matrix projection1,Matrix world2, Matrix view2, Matrix projection2,Matrix world3, Matrix view3, Matrix projection3,Matrix world4, Matrix view4, Matrix projection4,
...
Test
private void UpdateMatricesOptimized(ref Matrix world0, ref Matrix view0, ref Matrix projection0,ref Matrix world1, ref Matrix view1, ref Matrix projection1,ref Matrix world2, ref Matrix view2, ref Matrix projection2,ref Matrix world3, ref Matrix view3, ref Matrix projection3,ref Matrix world4, ref Matrix view4, ref Matrix projection4,ref Matrix world5, ref Matrix view5, ref Matrix projection5,
…
Memoria compartida entre structs
public struct Vector
{
public float X;
public float Y;
public float Z;
public Vector(float x, float y, float z)
{
this.X = x;
this.Y = y;
this.Z = z;
}
public override string ToString()
{
return string.Format("(X:{0} Y:{1} Z:{2})", X, Y, Z);
}
}
public void XNAMethod(ref Microsoft.Xna.Framework.Vector3 vector)
Primera Idea
Vector myVector = new Vector(1,2,3);
Vector3 xnaVector = (Vector3)myVector;
Error 1 Cannot convert type 'WindowsGame1.Vector' to 'Microsoft.Xna.Framework.Vector3'
Vector myVector = new Vector(1,2,3);
Vector3 xnaVector = new Vector3() { X = myVector.X, Y = myVector.Y, Z = myVector.Z };
Segunda idea[StructLayout(LayoutKind.Explicit)]
public struct UnionVector
{
[FieldOffset(0)]
public Microsoft.Xna.Framework.Vector3 XnaVector;
[FieldOffset(0)]
public OpenTK.Vector3 OpenTkVector;
[FieldOffset(0)]
public float X;
[FieldOffset(4)]
public float Y;
[FieldOffset(8)]
public float Z;
}
UnionVector myVector = new UnionVector() { X = 1, Y = 2, Z = 3};
Vector3 xnaVector = myVector.XnaVector;
OpenTK.Vector3 oTKVector3 = myVector.OpenTkVector;
Tercera ideaVector vector = new Vector(1, 2, 3);
unsafe
{
// Creamos un puntero de nuestro tipo de struct que apunta a la dirección
de memoria de nuestro vector.
Vector* pVector = &vector;
// Creamos un puntero del tipo de struct de XNA y hacemos un casting entre
punteros.
Vector3* pVector3 = (Vector3 *)pVector;
// Los métodos de XNA no permiten pasar como parámetro un puntero, por lo
que necesitamos la última conversión.
Vector3 vector3 = *pVector3;
XNAMethod(vector3);
}
Tercera idea
Vector vector = new Vector(1, 2, 3);
unsafe
{
XNAMethod(*(Vector3*)&vector);
}
Vector vector = new Vector(1, 2, 3);
unsafe
{
XNAMethod(ref *(Vector3*)&vector);
}