From: Henrik Gramner Date: Thu, 28 Jul 2016 19:58:40 +0000 (+0200) Subject: cli: Prefetch yuv/y4m input frames on Windows 8 and newer X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=aae177c55141460f442de0572c4a434bf2ae20bc;p=libx264 cli: Prefetch yuv/y4m input frames on Windows 8 and newer Use PrefetchVirtualMemory() (if available) on memory-mapped input frames. Significantly improves performance when the source file is not already present in the OS page cache by asking the OS to bring in those pages from disk using large, concurrent I/O requests. Most beneficial on fast encoding settings. Up to 40% faster overall with --preset ultrafast, and up to 20% faster overall with --preset veryfast. This API was introduced in Windows 8, so call it conditionally. On older Windows systems the previous behavior remains unchanged. --- diff --git a/input/avs.c b/input/avs.c index 6eab41f9..25732e41 100644 --- a/input/avs.c +++ b/input/avs.c @@ -34,7 +34,6 @@ #define avs_close dlclose #define avs_address dlsym #else -#include #define avs_open() LoadLibraryW( L"avisynth" ) #define avs_close FreeLibrary #define avs_address GetProcAddress diff --git a/input/ffms.c b/input/ffms.c index 35dc7cac..a2a87cef 100644 --- a/input/ffms.c +++ b/input/ffms.c @@ -33,10 +33,6 @@ #include #include -#ifdef _WIN32 -#include -#endif - #define PROGRESS_LENGTH 36 typedef struct diff --git a/input/input.c b/input/input.c index 82d32c39..90083989 100644 --- a/input/input.c +++ b/input/input.c @@ -28,7 +28,6 @@ #ifdef _WIN32 #include -#include #elif HAVE_MMAP #include #include @@ -154,6 +153,8 @@ int x264_cli_mmap_init( cli_mmap_t *h, FILE *fh ) SYSTEM_INFO si; GetSystemInfo( &si ); h->align_mask = si.dwAllocationGranularity - 1; + h->prefetch_virtual_memory = (void*)GetProcAddress( GetModuleHandleW( L"kernel32.dll" ), "PrefetchVirtualMemory" ); + h->process_handle = GetCurrentProcess(); h->map_handle = CreateFileMappingW( osfhandle, NULL, PAGE_READONLY, 0, 0, NULL ); return !h->map_handle; } @@ -173,9 +174,16 @@ void *x264_cli_mmap( cli_mmap_t *h, int64_t offset, size_t size ) size += align; #ifdef _WIN32 uint8_t *base = MapViewOfFile( h->map_handle, FILE_MAP_READ, offset >> 32, offset, size ); - /* TODO: Would PrefetchVirtualMemory() (only available on Win8+) be beneficial? */ if( base ) + { + /* PrefetchVirtualMemory() is only available on Windows 8 and newer. */ + if( h->prefetch_virtual_memory ) + { + struct { void *addr; size_t size; } mem_range = { base, size }; + h->prefetch_virtual_memory( h->process_handle, 1, &mem_range, 0 ); + } return base + align; + } #else uint8_t *base = mmap( NULL, size, PROT_READ, MAP_PRIVATE, h->fd, offset ); if( base != MAP_FAILED ) diff --git a/input/input.h b/input/input.h index 9e72bab8..d9a716fd 100644 --- a/input/input.h +++ b/input/input.h @@ -30,6 +30,10 @@ #include "x264cli.h" +#ifdef _WIN32 +#include +#endif + /* options that are used by only some demuxers */ typedef struct { @@ -135,7 +139,9 @@ typedef struct { int align_mask; #ifdef _WIN32 - void *map_handle; + BOOL (WINAPI *prefetch_virtual_memory)( HANDLE, ULONG_PTR, PVOID, ULONG ); + HANDLE process_handle; + HANDLE map_handle; #elif HAVE_MMAP int fd; #endif