public float sampleTrilinear(Array3D <float> noise, Vector3 pos) { var min = pos.ToFloored(); var f = pos - min; /*var q000 = noise.GetTiled(new Point3(0, 0, 0) + min); * var q100 = noise.GetTiled(new Point3(1, 0, 0) + min); * var q010 = noise.GetTiled(new Point3(0, 1, 0) + min); * var q001 = noise.GetTiled(new Point3(0, 0, 1) + min); * var q110 = noise.GetTiled(new Point3(1, 1, 0) + min); * var q011 = noise.GetTiled(new Point3(0, 1, 1) + min); * var q101 = noise.GetTiled(new Point3(1, 0, 1) + min); * var q111 = noise.GetTiled(new Point3(1, 1, 1) + min);*/ var x0 = TWMath.nfmod(min.X + 0, noise.Size.X);; var y0 = TWMath.nfmod(min.Y + 0, noise.Size.Y); var z0 = TWMath.nfmod(min.Z + 0, noise.Size.Z); var x1 = TWMath.nfmod(x0 + 1, noise.Size.X); var y1 = TWMath.nfmod(y0 + 1, noise.Size.Y); var z1 = TWMath.nfmod(z0 + 1, noise.Size.Z); var q000 = noise.GetFast(x0, y0, z0); var q100 = noise.GetFast(x1, y0, z0); var q010 = noise.GetFast(x0, y1, z0); var q001 = noise.GetFast(x0, y0, z1); var q110 = noise.GetFast(x1, y1, z0); var q011 = noise.GetFast(x0, y1, z1); var q101 = noise.GetFast(x1, y0, z1); var q111 = noise.GetFast(x1, y1, z1); var ret = TWMath.triLerp(f.dx(), q000, q100, q001, q101, q010, q110, q011, q111); return(ret); }
public T GetTiled(Point2 pos) { // Dont call the this[] directly, its about 20% slower when i tested it. Probably because of the out of bounds check // TODO: since this is always in bounds, maybe try using 'unsafe' and pointers to avoid the C# array bounds checking? Point2 point3 = Size; // Reading this out is a bit faster var x = TWMath.nfmod(pos.X, point3.X); var y = TWMath.nfmod(pos.Y, point3.Y); return(arr[y * Size.X + x]); }
public T GetTiledFast(int x, int y, int z) { // Dont call the this[] directly, its about 20% slower when i tested it. Probably because of the out of bounds check // TODO: since this is always in bounds, maybe try using 'unsafe' and pointers to avoid the C# array bounds checking? Point3 point3 = Size; // Reading this out is a bit faster x = TWMath.nfmod(x, point3.X); y = TWMath.nfmod(y, point3.Y); z = TWMath.nfmod(z, point3.Z); return(arr[x, y, z]); }
public void TestAccessPerformance() { var size = 100; var times = 10000; var arr = new float[size, size, size]; var multiDim = PerformanceHelper.Measure(() => { for (int j = 0; j < times; j++) { for (int i = 0; i < size - 2; i++) { var val = arr[i, i + 1, i + 2]; var val2 = arr[i + 1, i + 2, i]; } } }); Console.WriteLine("Multidim: " + multiDim.PrettyPrint()); var arr2 = new float[size * size * size]; var singleDim = PerformanceHelper.Measure(() => { for (int j = 0; j < times; j++) { for (int i = 0; i < size - 2; i++) { var val = arr2[(i + (i + 1) * size) * size + i + 2]; var val2 = arr2[(i + (i + 2) * size) * size + i + 1]; } } }); Console.WriteLine("SingleDim: " + singleDim.PrettyPrint()); Assert.Less(singleDim, multiDim); var arr3d = new Array3D <float>(new Point3(size, size, size)); var arr3DSpeed = PerformanceHelper.Measure(() => { for (int j = 0; j < times; j++) { for (int i = 0; i < size - 2; i++) { var val = arr3d[new Point3(i, i + 1, i + 2)]; var val2 = arr3d[new Point3(-i, -i + 1, -i + 2)]; } } }); Console.WriteLine("arr3d[]: " + arr3DSpeed.PrettyPrint()); var arr3DFastSpeed = PerformanceHelper.Measure(() => { for (int j = 0; j < times; j++) { for (int i = 0; i < size - 2; i++) { var val = arr3d.GetFast(i, i + 1, i + 2); var val2 = arr3d.GetFast(i, i + 2, i + 1); } } }); Console.WriteLine("arr3d.GetFast:" + arr3DFastSpeed.PrettyPrint()); var arr3DTiled = PerformanceHelper.Measure(() => { for (int j = 0; j < times; j++) { for (int i = 0; i < size - 2; i++) { var val = arr3d.GetTiled(new Point3(i, i + 1, i + 2)); var val2 = arr3d.GetTiled(new Point3(i, i + 2, i + 1)); } } }); Console.WriteLine("arr3d.GetTiled:" + arr3DTiled.PrettyPrint()); var arr3DTiledFast = PerformanceHelper.Measure(() => { for (int j = 0; j < times; j++) { for (int i = 0; i < size - 2; i++) { var val = arr3d.GetTiledFast(i, i + 1, i + 2); var val2 = arr3d.GetTiledFast(i, i + 2, i + 1); } } }); Console.WriteLine("arr3d.GetTiledFast:" + arr3DTiledFast.PrettyPrint()); var arr3DTiledCacheSize = PerformanceHelper.Measure(() => { for (int j = 0; j < times; j++) { for (int i = 0; i < size - 2; i++) { var a1 = TWMath.nfmod(i, size); var a2 = TWMath.nfmod(i + 1, size); var a3 = TWMath.nfmod(i + 2, size); var a4 = TWMath.nfmod(i, size); var a5 = TWMath.nfmod(i + 2, size); var a6 = TWMath.nfmod(i + 1, size); var val = arr3d.GetFast(a1, a2, a3); var val2 = arr3d.GetFast(a4, a5, a6); } } }); Console.WriteLine("arr3d.GetTiledCacheSize:" + arr3DTiledCacheSize.PrettyPrint()); var internalArr = arr3d.GetInternalField <float[, , ]>("arr"); var methodGet = PerformanceHelper.Measure(() => { for (int j = 0; j < times; j++) { for (int i = 0; i < size - 2; i++) { var val = Val(internalArr, i, i + 1, i + 2); var val2 = Val(internalArr, i, i + 2, i + 1); } } }); Console.WriteLine("DirectMethod: " + methodGet.PrettyPrint()); Assert.Less(arr3DFastSpeed, arr3DSpeed); }