[x264-devel] cli: Prefetch yuv/y4m input frames on Windows 8 and newer

Henrik Gramner git at videolan.org
Tue Sep 20 20:57:51 CEST 2016


x264 | branch: master | Henrik Gramner <henrik at gramner.com> | Thu Jul 28 21:58:40 2016 +0200| [aae177c55141460f442de0572c4a434bf2ae20bc] | committer: Anton Mitrofanov

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.

> http://git.videolan.org/gitweb.cgi/x264.git/?a=commit;h=aae177c55141460f442de0572c4a434bf2ae20bc
---

 input/avs.c   |  1 -
 input/ffms.c  |  4 ----
 input/input.c | 12 ++++++++++--
 input/input.h |  8 +++++++-
 4 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/input/avs.c b/input/avs.c
index 6eab41f..25732e4 100644
--- a/input/avs.c
+++ b/input/avs.c
@@ -34,7 +34,6 @@
 #define avs_close dlclose
 #define avs_address dlsym
 #else
-#include <windows.h>
 #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 35dc7ca..a2a87ce 100644
--- a/input/ffms.c
+++ b/input/ffms.c
@@ -33,10 +33,6 @@
 #include <libavcodec/avcodec.h>
 #include <libswscale/swscale.h>
 
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
 #define PROGRESS_LENGTH 36
 
 typedef struct
diff --git a/input/input.c b/input/input.c
index 82d32c3..9008398 100644
--- a/input/input.c
+++ b/input/input.c
@@ -28,7 +28,6 @@
 
 #ifdef _WIN32
 #include <io.h>
-#include <windows.h>
 #elif HAVE_MMAP
 #include <sys/mman.h>
 #include <unistd.h>
@@ -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 9e72bab..d9a716f 100644
--- a/input/input.h
+++ b/input/input.h
@@ -30,6 +30,10 @@
 
 #include "x264cli.h"
 
+#ifdef _WIN32
+#include <windows.h>
+#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



More information about the x264-devel mailing list