@@ -271,20 +271,29 @@ struct llama_mmap {
271
271
throw std::runtime_error (format (" MapViewOfFile failed: %s" , llama_format_win_err (error).c_str ()));
272
272
}
273
273
274
- #if _WIN32_WINNT >= _WIN32_WINNT_WIN8
275
274
if (prefetch) {
276
- // Advise the kernel to preload the mapped memory
277
- WIN32_MEMORY_RANGE_ENTRY range;
278
- range.VirtualAddress = addr;
279
- range.NumberOfBytes = (SIZE_T)size;
280
- if (!PrefetchVirtualMemory (GetCurrentProcess (), 1 , &range, 0 )) {
281
- fprintf (stderr, " warning: PrefetchVirtualMemory failed: %s\n " ,
282
- llama_format_win_err (GetLastError ()).c_str ());
275
+ // The PrefetchVirtualMemory API is only present on Windows 8 and above, so we
276
+ // will dynamically load it using GetProcAddress.
277
+ BOOL (WINAPI *pPrefetchVirtualMemory) (HANDLE, ULONG_PTR, PWIN32_MEMORY_RANGE_ENTRY, ULONG);
278
+ HMODULE hKernel32;
279
+
280
+ // This call is guaranteed to succeed.
281
+ hKernel32 = GetModuleHandleW (L" kernel32.dll" );
282
+
283
+ // This call may fail if on a pre-Win8 system.
284
+ pPrefetchVirtualMemory = reinterpret_cast <decltype (pPrefetchVirtualMemory)> (GetProcAddress (hKernel32, " PrefetchVirtualMemory" ));
285
+
286
+ if (pPrefetchVirtualMemory) {
287
+ // Advise the kernel to preload the mapped memory.
288
+ WIN32_MEMORY_RANGE_ENTRY range;
289
+ range.VirtualAddress = addr;
290
+ range.NumberOfBytes = (SIZE_T)size;
291
+ if (!pPrefetchVirtualMemory (GetCurrentProcess (), 1 , &range, 0 )) {
292
+ fprintf (stderr, " warning: PrefetchVirtualMemory failed: %s\n " ,
293
+ llama_format_win_err (GetLastError ()).c_str ());
294
+ }
283
295
}
284
296
}
285
- #else
286
- #pragma message("warning: You are building for pre-Windows 8; prefetch not supported")
287
- #endif // _WIN32_WINNT >= _WIN32_WINNT_WIN8
288
297
}
289
298
290
299
~llama_mmap () {
0 commit comments