-
Notifications
You must be signed in to change notification settings - Fork 39
/
LargePages.cpp
91 lines (71 loc) · 2.33 KB
/
LargePages.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Alocation memory in Large Pages (2/4 MB), that may improve speed when accessing gigabytes of data in random order
#ifdef _WIN32
#include <windows.h>
const DWORD g_PageFlag0 = 0x1000;
const uint64_t g_PageMask0 = 0x1000-1;
DWORD g_PageFlag = g_PageFlag0;
uint64_t g_PageMask = g_PageMask0;
bool verbose = true;
#pragma comment(lib, "advapi32.lib")
void InitLargePages()
{
HANDLE hToken = 0;
LUID luid;
TOKEN_PRIVILEGES tp;
OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
LookupPrivilegeValue (NULL, "SeLockMemoryPrivilege", &luid);
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges (hToken, FALSE, &tp, sizeof(tp), 0, 0);
CloseHandle(hToken);
uint64_t size = 0x1000;
typedef SIZE_T (__stdcall *GetLPMP)();
GetLPMP LPM = (GetLPMP)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),"GetLargePageMinimum");
if (LPM) size = LPM();
if (size==0 || (size&(size-1))!=0) size=0x1000;
g_PageMask = size-1;
g_PageFlag = g_PageFlag0;
if (size>0x1000) g_PageFlag |= 0x20000000;
}
template< class T >
T* VAlloc (uint64_t size)
{
size *= sizeof(T);
uint64_t PageMask = g_PageMask;
uint64_t s = (size+PageMask) & (~PageMask);
if (s > size_t(-1)) {
return 0;
}
void* r = 0;
if (size > g_PageMask) {
r = VirtualAlloc(0, s, g_PageFlag, PAGE_READWRITE); // alloc using 2 MB pages only if the size is no less than one page
}
if (r==0 && PageMask!=g_PageMask0) {
PageMask = g_PageMask0;
s = (size+PageMask) & (~PageMask);
r = VirtualAlloc(0, size, g_PageFlag0, PAGE_READWRITE); // alloc using 4 KB pages, if preceding attempt failed
}
if (verbose) printf("Allocated %.0lf MiB with %s\n", s/1048576.0, PageMask==0x1fffff? "2MiB pages": PageMask==0xfff? "4KiB pages": "unknown pagesize");
return (T*)r;
}
template< class T >
void VFree( T* p )
{
VirtualFree(p, 0, MEM_RELEASE);
}
#else // _WIN32
bool verbose = true;
void InitLargePages() {}
template< class T >
T* VAlloc (uint64_t size)
{
if (verbose) printf("Allocated %.0lf MiB\n", (size*sizeof(T))/1048576.0);
return (T*) malloc(size*sizeof(T));
}
template< class T >
void VFree( T* p )
{
free(p);
}
#endif // _WIN32