diff --git a/benches/bench.rs b/benches/bench.rs
index a8f90d1d0fec420e8ee364bc960198903f4ce4cf..07fd9b402ccd58c6a60e17a153df0ee85e4c21d8 100644
--- a/benches/bench.rs
+++ b/benches/bench.rs
@@ -13,6 +13,7 @@ extern crate rand;
 extern crate rav1e;
 
 mod predict;
+mod me;
 
 use criterion::*;
 use rav1e::cdef::cdef_filter_frame;
@@ -138,9 +139,10 @@ criterion_group!(intra_prediction, predict::pred_bench,);
 criterion_group!(cfl, cfl_rdo);
 criterion_group!(cdef, cdef_frame);
 criterion_group!(write_block, write_b);
+criterion_group!(me, me::get_sad);
 
 #[cfg(feature = "comparative_bench")]
 criterion_main!(comparative::intra_prediction);
 
 #[cfg(not(feature = "comparative_bench"))]
-criterion_main!(write_block, intra_prediction, cdef, cfl);
+criterion_main!(write_block, intra_prediction, cdef, cfl, me);
diff --git a/benches/me.rs b/benches/me.rs
new file mode 100644
index 0000000000000000000000000000000000000000..0beac7b176bbacf50a08913edd66c317b21b5d6a
--- /dev/null
+++ b/benches/me.rs
@@ -0,0 +1,82 @@
+// Copyright (c) 2017-2018, The rav1e contributors. All rights reserved
+//
+// This source code is subject to the terms of the BSD 2 Clause License and
+// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+// was not distributed with this source code in the LICENSE file, you can
+// obtain it at www.aomedia.org/license/software. If the Alliance for Open
+// Media Patent License 1.0 was not distributed with this source code in the
+// PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+
+use criterion::*;
+use partition::*;
+use plane::*;
+use rand::{ChaChaRng, Rng, SeedableRng};
+use rav1e::me;
+
+fn fill_plane(ra: &mut ChaChaRng, plane: &mut Plane) {
+  let stride = plane.cfg.stride;
+  for row in plane.data.chunks_mut(stride) {
+    for mut pixel in row {
+      let v: u8 = ra.gen();
+      *pixel = v as u16;
+    }
+  }
+}
+
+fn new_plane(ra: &mut ChaChaRng, width: usize, height: usize) -> Plane {
+  let mut p = Plane::new(width, height, 0, 0, 128 + 8, 128 + 8);
+
+  fill_plane(ra, &mut p);
+
+  p
+}
+
+fn bench_get_sad(b: &mut Bencher, bs: &BlockSize) {
+  let mut ra = ChaChaRng::from_seed([0; 32]);
+  let bsw = bs.width();
+  let bsh = bs.height();
+  let w = 640;
+  let h = 480;
+  let input_plane = new_plane(&mut ra, w, h);
+  let rec_plane = new_plane(&mut ra, w, h);
+  let po = PlaneOffset { x: 0, y: 0 };
+
+  let mut plane_org = input_plane.slice(&po);
+  let mut plane_ref = rec_plane.slice(&po);
+
+  b.iter(|| {
+      let _ = me::get_sad(&mut plane_org, &mut plane_ref, bsw, bsh);
+      plane_org.y = 0;
+      plane_ref.y = 0;
+  })
+}
+
+pub fn get_sad(c: &mut Criterion) {
+  use partition::BlockSize::*;
+  let blocks = vec![
+    BLOCK_4X4,
+    BLOCK_4X8,
+    BLOCK_8X4,
+    BLOCK_8X8,
+    BLOCK_8X16,
+    BLOCK_16X8,
+    BLOCK_16X16,
+    BLOCK_16X32,
+    BLOCK_32X16,
+    BLOCK_32X32,
+    BLOCK_32X64,
+    BLOCK_64X32,
+    BLOCK_64X64,
+    BLOCK_64X128,
+    BLOCK_128X64,
+    BLOCK_128X128,
+    BLOCK_4X16,
+    BLOCK_16X4,
+    BLOCK_8X32,
+    BLOCK_32X8,
+    BLOCK_16X64,
+    BLOCK_64X16,
+  ];
+
+  c.bench_function_over_inputs("get_sad", bench_get_sad, blocks);
+}