Commit 1734712a authored by Frank Barchard's avatar Frank Barchard Committed by Commit Bot

Fix odd length HammingDistance

If length of HammingDistance was not a multiple of 4,
the result was incorrect.  The old tests did not catch this
so a new test is done to count 1s.

Bug: libyuv:740
Test: LibYUVCompareTest.TestHammingDistance
Change-Id: I93db5437821c597f1f162ac263d4a594bb83231f
Reviewed-on: https://chromium-review.googlesource.com/699614Reviewed-by: 's avatarrichard winterton <rrwinterton@gmail.com>
Reviewed-by: 's avatarCheng Wang <wangcheng@google.com>
Reviewed-by: 's avatarFrank Barchard <fbarchard@google.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
parent fecd7417
Name: libyuv Name: libyuv
URL: http://code.google.com/p/libyuv/ URL: http://code.google.com/p/libyuv/
Version: 1672 Version: 1673
License: BSD License: BSD
License File: LICENSE License File: LICENSE
......
...@@ -11,6 +11,6 @@ ...@@ -11,6 +11,6 @@
#ifndef INCLUDE_LIBYUV_VERSION_H_ #ifndef INCLUDE_LIBYUV_VERSION_H_
#define INCLUDE_LIBYUV_VERSION_H_ #define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 1672 #define LIBYUV_VERSION 1673
#endif // INCLUDE_LIBYUV_VERSION_H_ #endif // INCLUDE_LIBYUV_VERSION_H_
...@@ -115,8 +115,9 @@ uint64 ComputeHammingDistance(const uint8* src_a, ...@@ -115,8 +115,9 @@ uint64 ComputeHammingDistance(const uint8* src_a,
const uint8* src_b, const uint8* src_b,
int count) { int count) {
const int kBlockSize = 65536; const int kBlockSize = 65536;
const int kSimdSize = 64;
// SIMD for multiple of 64, and C for remainder // SIMD for multiple of 64, and C for remainder
int remainder = count & (kBlockSize - 1) & ~63; int remainder = count & (kBlockSize - 1) & ~(kSimdSize - 1);
uint64 diff = 0; uint64 diff = 0;
int i; int i;
uint32 (*HammingDistance)(const uint8* src_a, const uint8* src_b, int count) = uint32 (*HammingDistance)(const uint8* src_a, const uint8* src_b, int count) =
...@@ -159,7 +160,7 @@ uint64 ComputeHammingDistance(const uint8* src_a, ...@@ -159,7 +160,7 @@ uint64 ComputeHammingDistance(const uint8* src_a,
src_a += remainder; src_a += remainder;
src_b += remainder; src_b += remainder;
} }
remainder = count & 31; remainder = count & (kSimdSize - 1);
if (remainder) { if (remainder) {
diff += HammingDistance_C(src_a, src_b, remainder); diff += HammingDistance_C(src_a, src_b, remainder);
} }
......
...@@ -18,7 +18,7 @@ extern "C" { ...@@ -18,7 +18,7 @@ extern "C" {
#endif #endif
#if ORIGINAL_OPT #if ORIGINAL_OPT
uint32 HammingDistance_C(const uint8* src_a, const uint8* src_b, int count) { uint32 HammingDistance_C1(const uint8* src_a, const uint8* src_b, int count) {
uint32 diff = 0u; uint32 diff = 0u;
int i; int i;
...@@ -58,6 +58,16 @@ uint32 HammingDistance_C(const uint8* src_a, const uint8* src_b, int count) { ...@@ -58,6 +58,16 @@ uint32 HammingDistance_C(const uint8* src_a, const uint8* src_b, int count) {
src_a += 4; src_a += 4;
src_b += 4; src_b += 4;
} }
for (; i < count; ++i) {
uint32 x = *src_a ^ *src_b;
uint32 u = x - ((x >> 1) & 0x55);
u = ((u >> 2) & 0x33) + (u & 0x33);
diff += (u + (u >> 4)) & 0x0f;
src_a += 1;
src_b += 1;
}
return diff; return diff;
} }
......
...@@ -316,6 +316,23 @@ TEST_F(LibYUVCompareTest, BenchmarkHammingDistance) { ...@@ -316,6 +316,23 @@ TEST_F(LibYUVCompareTest, BenchmarkHammingDistance) {
free_aligned_buffer_page_end(src_b); free_aligned_buffer_page_end(src_b);
} }
TEST_F(LibYUVCompareTest, TestHammingDistance) {
align_buffer_page_end(src_a, benchmark_width_ * benchmark_height_);
align_buffer_page_end(src_b, benchmark_width_ * benchmark_height_);
memset(src_a, 255u, benchmark_width_ * benchmark_height_);
memset(src_b, 0, benchmark_width_ * benchmark_height_);
uint64 h1 = 0;
for (int i = 0; i < benchmark_iterations_; ++i) {
h1 = ComputeHammingDistance(src_a, src_b,
benchmark_width_ * benchmark_height_);
}
EXPECT_EQ(benchmark_width_ * benchmark_height_ * 8ULL, h1);
free_aligned_buffer_page_end(src_a);
free_aligned_buffer_page_end(src_b);
}
TEST_F(LibYUVCompareTest, BenchmarkSumSquareError_Opt) { TEST_F(LibYUVCompareTest, BenchmarkSumSquareError_Opt) {
const int kMaxWidth = 4096 * 3; const int kMaxWidth = 4096 * 3;
align_buffer_page_end(src_a, kMaxWidth); align_buffer_page_end(src_a, kMaxWidth);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment