shithub: libvpx

Download patch

ref: ccb06a9fb15b9c10099cef28ff1240eb9ffa9390
parent: 50d1a4aa725fbc78ee89ffde5e83b4ee4fe4893e
author: Clement Courbet <courbet@google.com>
date: Tue Jan 7 04:08:24 EST 2020

Avoid reloads in vp9_read_mode_info.

The compiler cannot prove that the buffers do not alias, so it has to emit a
reload. On our internal workloads, the reloads are about 1% of the total time
spent decoding frames.

The loop before the change:

movzwl 0x8(%r15), %edx       # load ref_frame
addq $0xc, %rax
movw %dx, -0x4(%rax)         # store ref_frame
movq 0xc(%r15), %rdx         # load mv
movq %rdx, -0xc(%rax)        # store mv
cmpq %rax, %rcx
jne -0x1a

The loop after the change:

movw %r9w, 0x8(%rax)         # store cached ref_frame
addq $0xc, %rax
movq %r8, -0xc(%rax)         # store cached mv
cmpq %rax, %rdx
jne -0x12

Change-Id: Ia1e9634bcabb4d7e06ed60f470bc4cd67f5ab27e

--- a/vp9/decoder/vp9_decodemv.c
+++ b/vp9/decoder/vp9_decodemv.c
@@ -820,13 +820,21 @@
   if (frame_is_intra_only(cm)) {
     read_intra_frame_mode_info(cm, xd, mi_row, mi_col, r, x_mis, y_mis);
   } else {
+    // Cache mi->ref_frame and mi->mv so that the compiler can prove that they
+    // are constant for the duration of the loop and avoids reloading them.
+    MV_REFERENCE_FRAME mi_ref_frame[2];
+    int_mv mi_mv[2];
+
     read_inter_frame_mode_info(pbi, xd, mi_row, mi_col, r, x_mis, y_mis);
 
+    copy_ref_frame_pair(mi_ref_frame, mi->ref_frame);
+    copy_mv_pair(mi_mv, mi->mv);
+
     for (h = 0; h < y_mis; ++h) {
       for (w = 0; w < x_mis; ++w) {
         MV_REF *const mv = frame_mvs + w;
-        copy_ref_frame_pair(mv->ref_frame, mi->ref_frame);
-        copy_mv_pair(mv->mv, mi->mv);
+        copy_ref_frame_pair(mv->ref_frame, mi_ref_frame);
+        copy_mv_pair(mv->mv, mi_mv);
       }
       frame_mvs += cm->mi_cols;
     }