Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(567)

Unified Diff: media/base/sinc_resampler_unittest.cc

Issue 10803003: Add SSE optimizations to SincResampler. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix compile error. Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/base/sinc_resampler.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/base/sinc_resampler_unittest.cc
diff --git a/media/base/sinc_resampler_unittest.cc b/media/base/sinc_resampler_unittest.cc
index 9bf7ba4409b97d0ffbdbfbc267f900535df96073..fa358e13045c82a2035070557fb0c2d793b35499 100644
--- a/media/base/sinc_resampler_unittest.cc
+++ b/media/base/sinc_resampler_unittest.cc
@@ -9,9 +9,10 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/command_line.h"
#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/stringprintf.h"
+#include "base/string_number_conversions.h"
+#include "base/time.h"
#include "media/base/sinc_resampler.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -20,6 +21,12 @@ using testing::_;
namespace media {
+static const double kSampleRateRatio = 192000.0 / 44100.0;
+static const double kKernelInterpolationFactor = 0.5;
+
+// Command line switch for runtime adjustment of ConvolveBenchmark iterations.
+static const char kConvolveIterations[] = "convolve-iterations";
+
// Helper class to ensure ChunkedResample() functions properly.
class MockSource {
public:
@@ -33,7 +40,6 @@ TEST(SincResamplerTest, ChunkedResample) {
// Choose a high ratio of input to output samples which will result in quick
// exhaustion of SincResampler's internal buffers.
- static const double kSampleRateRatio = 192000.0 / 44100.0;
SincResampler resampler(
kSampleRateRatio,
base::Bind(&MockSource::ProvideInput, base::Unretained(&mock_source)));
@@ -52,6 +58,102 @@ TEST(SincResamplerTest, ChunkedResample) {
resampler.Resample(resampled_destination.get(), max_chunk_size);
}
+// Ensure various optimized Convolve() methods return the same value. Only run
+// this test if other optimized methods exist, otherwise the default Convolve()
+// will be tested by the parameterized SincResampler tests below.
+#if defined(ARCH_CPU_X86_FAMILY) && defined(__SSE__)
+TEST(SincResamplerTest, Convolve) {
+ // Initialize a dummy resampler.
+ MockSource mock_source;
+ SincResampler resampler(
+ kSampleRateRatio,
+ base::Bind(&MockSource::ProvideInput, base::Unretained(&mock_source)));
+
+ // Convolve_SSE() is slightly more precise than Convolve_C(), so comparison
+ // must be done using an epsilon.
+ static const double kEpsilon = 0.00000005;
+
+ // Use a kernel from SincResampler as input and kernel data, this has the
+ // benefit of already being properly sized and aligned for Convolve_SSE().
+ double result = resampler.Convolve_C(
+ resampler.kernel_storage_.get(), resampler.kernel_storage_.get(),
+ resampler.kernel_storage_.get(), kKernelInterpolationFactor);
+ double result2 = resampler.Convolve_SSE(
+ resampler.kernel_storage_.get(), resampler.kernel_storage_.get(),
+ resampler.kernel_storage_.get(), kKernelInterpolationFactor);
+ EXPECT_NEAR(result2, result, kEpsilon);
+
+ // Test Convolve_SSE() w/ unaligned input pointer.
+ result = resampler.Convolve_C(
+ resampler.kernel_storage_.get() + 1, resampler.kernel_storage_.get(),
+ resampler.kernel_storage_.get(), kKernelInterpolationFactor);
+ result2 = resampler.Convolve_SSE(
+ resampler.kernel_storage_.get() + 1, resampler.kernel_storage_.get(),
+ resampler.kernel_storage_.get(), kKernelInterpolationFactor);
+ EXPECT_NEAR(result2, result, kEpsilon);
+}
+#endif
+
+// Benchmark for the various Convolve() methods. Make sure to build with
+// branding=Chrome so that DCHECKs are compiled out when benchmarking. Original
+// benchmarks were run with --convolve-iterations=50000000.
+TEST(SincResamplerTest, ConvolveBenchmark) {
+ // Initialize a dummy resampler.
+ MockSource mock_source;
+ SincResampler resampler(
+ kSampleRateRatio,
+ base::Bind(&MockSource::ProvideInput, base::Unretained(&mock_source)));
+
+ // Retrieve benchmark iterations from command line.
+ int convolve_iterations = 10;
+ std::string iterations(CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ kConvolveIterations));
+ if (!iterations.empty())
+ base::StringToInt(iterations, &convolve_iterations);
+
+ printf("Benchmarking %d iterations:\n", convolve_iterations);
+
+ // Benchmark Convolve_C().
+ base::TimeTicks start = base::TimeTicks::HighResNow();
+ for (int i = 0; i < convolve_iterations; ++i) {
+ resampler.Convolve_C(
+ resampler.kernel_storage_.get(), resampler.kernel_storage_.get(),
+ resampler.kernel_storage_.get(), kKernelInterpolationFactor);
+ }
+ double total_time_c_ms =
+ (base::TimeTicks::HighResNow() - start).InMillisecondsF();
+ printf("Convolve_C took %.2fms.\n", total_time_c_ms);
+
+#if defined(ARCH_CPU_X86_FAMILY) && defined(__SSE__)
+ // Benchmark Convolve_SSE() with unaligned input pointer.
+ start = base::TimeTicks::HighResNow();
+ for (int j = 0; j < convolve_iterations; ++j) {
+ resampler.Convolve_SSE(
+ resampler.kernel_storage_.get() + 1, resampler.kernel_storage_.get(),
+ resampler.kernel_storage_.get(), kKernelInterpolationFactor);
+ }
+ double total_time_sse_unaligned_ms =
+ (base::TimeTicks::HighResNow() - start).InMillisecondsF();
+ printf("Convolve_SSE (unaligned) took %.2fms; which is %.2fx faster than"
+ " Convolve_C.\n", total_time_sse_unaligned_ms,
+ total_time_c_ms / total_time_sse_unaligned_ms);
+
+ // Benchmark Convolve_SSE() with aligned input pointer.
+ start = base::TimeTicks::HighResNow();
+ for (int j = 0; j < convolve_iterations; ++j) {
+ resampler.Convolve_SSE(
+ resampler.kernel_storage_.get(), resampler.kernel_storage_.get(),
+ resampler.kernel_storage_.get(), kKernelInterpolationFactor);
+ }
+ double total_time_sse_aligned_ms =
+ (base::TimeTicks::HighResNow() - start).InMillisecondsF();
+ printf("Convolve_SSE (aligned) took %.2fms; which is %.2fx faster than"
+ " Convolve_C and %.2fx faster than Convolve_SSE (unaligned).\n",
+ total_time_sse_aligned_ms, total_time_c_ms / total_time_sse_aligned_ms,
+ total_time_sse_unaligned_ms / total_time_sse_aligned_ms);
+#endif
+}
+
// Fake audio source for testing the resampler. Generates a sinusoidal linear
// chirp (http://en.wikipedia.org/wiki/Chirp) which can be tuned to stress the
// resampler for the specific sample rate conversion being used.
« no previous file with comments | « media/base/sinc_resampler.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698