• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/memory/aligned_memory.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/time/time.h"
8 #include "media/base/vector_math.h"
9 #include "media/base/vector_math_testing.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "testing/perf/perf_test.h"
12 
13 using base::TimeTicks;
14 using std::fill;
15 
16 namespace media {
17 
18 static const int kBenchmarkIterations = 200000;
19 static const int kEWMABenchmarkIterations = 50000;
20 static const float kScale = 0.5;
21 static const int kVectorSize = 8192;
22 
23 class VectorMathPerfTest : public testing::Test {
24  public:
VectorMathPerfTest()25   VectorMathPerfTest() {
26     // Initialize input and output vectors.
27     input_vector_.reset(static_cast<float*>(base::AlignedAlloc(
28         sizeof(float) * kVectorSize, vector_math::kRequiredAlignment)));
29     output_vector_.reset(static_cast<float*>(base::AlignedAlloc(
30         sizeof(float) * kVectorSize, vector_math::kRequiredAlignment)));
31     fill(input_vector_.get(), input_vector_.get() + kVectorSize, 1.0f);
32     fill(output_vector_.get(), output_vector_.get() + kVectorSize, 0.0f);
33   }
34 
RunBenchmark(void (* fn)(const float[],float,int,float[]),bool aligned,const std::string & test_name,const std::string & trace_name)35   void RunBenchmark(void (*fn)(const float[], float, int, float[]),
36                     bool aligned,
37                     const std::string& test_name,
38                     const std::string& trace_name) {
39     TimeTicks start = TimeTicks::HighResNow();
40     for (int i = 0; i < kBenchmarkIterations; ++i) {
41       fn(input_vector_.get(),
42          kScale,
43          kVectorSize - (aligned ? 0 : 1),
44          output_vector_.get());
45     }
46     double total_time_milliseconds =
47         (TimeTicks::HighResNow() - start).InMillisecondsF();
48     perf_test::PrintResult(test_name,
49                            "",
50                            trace_name,
51                            kBenchmarkIterations / total_time_milliseconds,
52                            "runs/ms",
53                            true);
54   }
55 
RunBenchmark(std::pair<float,float> (* fn)(float,const float[],int,float),int len,const std::string & test_name,const std::string & trace_name)56   void RunBenchmark(
57       std::pair<float, float> (*fn)(float, const float[], int, float),
58       int len,
59       const std::string& test_name,
60       const std::string& trace_name) {
61     TimeTicks start = TimeTicks::HighResNow();
62     for (int i = 0; i < kEWMABenchmarkIterations; ++i) {
63       fn(0.5f, input_vector_.get(), len, 0.1f);
64     }
65     double total_time_milliseconds =
66         (TimeTicks::HighResNow() - start).InMillisecondsF();
67     perf_test::PrintResult(test_name,
68                            "",
69                            trace_name,
70                            kEWMABenchmarkIterations / total_time_milliseconds,
71                            "runs/ms",
72                            true);
73   }
74 
75  protected:
76   scoped_ptr<float, base::AlignedFreeDeleter> input_vector_;
77   scoped_ptr<float, base::AlignedFreeDeleter> output_vector_;
78 
79   DISALLOW_COPY_AND_ASSIGN(VectorMathPerfTest);
80 };
81 
82 // Define platform dependent function names for SIMD optimized methods.
83 #if defined(ARCH_CPU_X86_FAMILY)
84 #define FMAC_FUNC FMAC_SSE
85 #define FMUL_FUNC FMUL_SSE
86 #define EWMAAndMaxPower_FUNC EWMAAndMaxPower_SSE
87 #elif defined(ARCH_CPU_ARM_FAMILY) && defined(USE_NEON)
88 #define FMAC_FUNC FMAC_NEON
89 #define FMUL_FUNC FMUL_NEON
90 #define EWMAAndMaxPower_FUNC EWMAAndMaxPower_NEON
91 #endif
92 
93 // Benchmark for each optimized vector_math::FMAC() method.
TEST_F(VectorMathPerfTest,FMAC)94 TEST_F(VectorMathPerfTest, FMAC) {
95   // Benchmark FMAC_C().
96   RunBenchmark(
97       vector_math::FMAC_C, true, "vector_math_fmac", "unoptimized");
98 #if defined(FMAC_FUNC)
99   // Benchmark FMAC_FUNC() with unaligned size.
100   ASSERT_NE((kVectorSize - 1) % (vector_math::kRequiredAlignment /
101                                  sizeof(float)), 0U);
102   RunBenchmark(
103       vector_math::FMAC_FUNC, false, "vector_math_fmac", "optimized_unaligned");
104   // Benchmark FMAC_FUNC() with aligned size.
105   ASSERT_EQ(kVectorSize % (vector_math::kRequiredAlignment / sizeof(float)),
106             0U);
107   RunBenchmark(
108       vector_math::FMAC_FUNC, true, "vector_math_fmac", "optimized_aligned");
109 #endif
110 }
111 
112 // Benchmark for each optimized vector_math::FMUL() method.
TEST_F(VectorMathPerfTest,FMUL)113 TEST_F(VectorMathPerfTest, FMUL) {
114   // Benchmark FMUL_C().
115   RunBenchmark(
116       vector_math::FMUL_C, true, "vector_math_fmul", "unoptimized");
117 #if defined(FMUL_FUNC)
118   // Benchmark FMUL_FUNC() with unaligned size.
119   ASSERT_NE((kVectorSize - 1) % (vector_math::kRequiredAlignment /
120                                  sizeof(float)), 0U);
121   RunBenchmark(
122       vector_math::FMUL_FUNC, false, "vector_math_fmul", "optimized_unaligned");
123   // Benchmark FMUL_FUNC() with aligned size.
124   ASSERT_EQ(kVectorSize % (vector_math::kRequiredAlignment / sizeof(float)),
125             0U);
126   RunBenchmark(
127       vector_math::FMUL_FUNC, true, "vector_math_fmul", "optimized_aligned");
128 #endif
129 }
130 
131 // Benchmark for each optimized vector_math::EWMAAndMaxPower() method.
TEST_F(VectorMathPerfTest,EWMAAndMaxPower)132 TEST_F(VectorMathPerfTest, EWMAAndMaxPower) {
133   // Benchmark EWMAAndMaxPower_C().
134   RunBenchmark(vector_math::EWMAAndMaxPower_C,
135                kVectorSize,
136                "vector_math_ewma_and_max_power",
137                "unoptimized");
138 #if defined(EWMAAndMaxPower_FUNC)
139   // Benchmark EWMAAndMaxPower_FUNC() with unaligned size.
140   ASSERT_NE((kVectorSize - 1) % (vector_math::kRequiredAlignment /
141                                  sizeof(float)), 0U);
142   RunBenchmark(vector_math::EWMAAndMaxPower_FUNC,
143                kVectorSize - 1,
144                "vector_math_ewma_and_max_power",
145                "optimized_unaligned");
146   // Benchmark EWMAAndMaxPower_FUNC() with aligned size.
147   ASSERT_EQ(kVectorSize % (vector_math::kRequiredAlignment / sizeof(float)),
148             0U);
149   RunBenchmark(vector_math::EWMAAndMaxPower_FUNC,
150                kVectorSize,
151                "vector_math_ewma_and_max_power",
152                "optimized_aligned");
153 #endif
154 }
155 
156 } // namespace media
157