]> granicus.if.org Git - libvpx/commitdiff
Avoid reloads in vp9_read_mode_info.
authorClement Courbet <courbet@google.com>
Tue, 7 Jan 2020 08:08:24 +0000 (09:08 +0100)
committerClement Courbet <courbet@google.com>
Tue, 7 Jan 2020 16:04:36 +0000 (17:04 +0100)
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

vp9/decoder/vp9_decodemv.c

index 49c6753948bc67fae111917b426ddad8ca619cf5..8a8d2ad86ee6d9eb33f38bf4cbfe36337a62bee6 100644 (file)
@@ -820,13 +820,21 @@ void vp9_read_mode_info(TileWorkerData *twd, VP9Decoder *const pbi, int mi_row,
   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;
     }