public static class ExecuteAllocator
{
public static nint Alloc(int size)
{
return VirtualAlloc(IntPtr.Zero,
(IntPtr)4096,
AllocationType.Commit | AllocationType.Reserve,
MemoryProtection.ExecuteReadWrite);
}
public static void Free(nint ptr) => VirtualFree(ptr, 0, FreeType.Release);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr VirtualAlloc(
IntPtr lpAddress,
IntPtr dwSize,
AllocationType flAllocationType,
MemoryProtection flProtect);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool VirtualFree(
IntPtr lpAddress,
IntPtr dwSize,
FreeType dwFreeType);
[Flags]
public enum AllocationType
{
Commit = 0x1000,
Reserve = 0x2000,
Decommit = 0x4000,
Release = 0x8000,
Reset = 0x80000,
Physical = 0x400000,
TopDown = 0x100000,
WriteWatch = 0x200000,
LargePages = 0x20000000
}
[Flags]
public enum MemoryProtection
{
Execute = 0x10,
ExecuteRead = 0x20,
ExecuteReadWrite = 0x40,
ExecuteWriteCopy = 0x80,
NoAccess = 0x01,
ReadOnly = 0x02,
ReadWrite = 0x04,
WriteCopy = 0x08,
GuardModifierflag = 0x100,
NoCacheModifierflag = 0x200,
WriteCombineModifierflag = 0x400
}
[Flags]
public enum FreeType
{
Decommit = 0x4000,
Release = 0x8000,
}
}
Ясно, что эта оптимизация не работает хорошо 100% времени. И без нее на конкретно вашем компьютере может хватать вычислительной мощности для 60фпс. Но если она работает достаточно часто, то почему бы ее и не применить?
А профит тут в том, что вы вот так вот обходите не все дерево. а только маленькую его часть.
1. Я еще заметил, точнее не учел, что если if(t>max) выполнится, то очевидно второй if(t 2. Не учел оптимизацию, в циклах что можно без cmp инструкции счетчик уменьшать, и ждать когда он станет 0.
dec edx
jne Begin
быстрее(при том я даже видел этот пример в preview net 9.0 но забыл)
3. Не учел раскрутки если раскрутить хотя бы на 2 то быстрее. Если заменить на чтение 64бит сразу
asm.mov(r11, __[rcx + rax * 4]); //r11d 1 часть.
asm.shr(r11,32); // 2 часть.
4. Еще можно ускорить, если изменения счетчика(или итератора) поставить сразу после операций чтения, что бы не просаживало конвеер, так как следующая операция под ним ждет конца чтения.
А замедление связано похоже с тем, что компилятор c# получает структуру minmax тем, что кладет на стек 2 store-ами ее поля, и затем считывает, вместо того что бы просто вернуть min | max<<32
Что с этим редактором, как он в тихоря удаляет исправления, в разных местах, что это "if(t 2." там должно быть выражения а оно пропало