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.
6 #include "base/memory/aligned_memory.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/time/time.h"
9 #include "media/base/vector_math.h"
10 #include "media/base/vector_math_testing.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "testing/perf/perf_test.h"
14 using base::TimeTicks
;
19 static const int kBenchmarkIterations
= 200000;
20 static const int kEWMABenchmarkIterations
= 50000;
21 static const float kScale
= 0.5;
22 static const int kVectorSize
= 8192;
24 class VectorMathPerfTest
: public testing::Test
{
26 VectorMathPerfTest() {
27 // Initialize input and output vectors.
28 input_vector_
.reset(static_cast<float*>(base::AlignedAlloc(
29 sizeof(float) * kVectorSize
, vector_math::kRequiredAlignment
)));
30 output_vector_
.reset(static_cast<float*>(base::AlignedAlloc(
31 sizeof(float) * kVectorSize
, vector_math::kRequiredAlignment
)));
32 fill(input_vector_
.get(), input_vector_
.get() + kVectorSize
, 1.0f
);
33 fill(output_vector_
.get(), output_vector_
.get() + kVectorSize
, 0.0f
);
36 void RunBenchmark(void (*fn
)(const float[], float, int, float[]),
38 const std::string
& test_name
,
39 const std::string
& trace_name
) {
40 TimeTicks start
= TimeTicks::HighResNow();
41 for (int i
= 0; i
< kBenchmarkIterations
; ++i
) {
42 fn(input_vector_
.get(),
44 kVectorSize
- (aligned
? 0 : 1),
45 output_vector_
.get());
47 double total_time_milliseconds
=
48 (TimeTicks::HighResNow() - start
).InMillisecondsF();
49 perf_test::PrintResult(test_name
,
52 kBenchmarkIterations
/ total_time_milliseconds
,
58 std::pair
<float, float> (*fn
)(float, const float[], int, float),
60 const std::string
& test_name
,
61 const std::string
& trace_name
) {
62 TimeTicks start
= TimeTicks::HighResNow();
63 for (int i
= 0; i
< kEWMABenchmarkIterations
; ++i
) {
64 fn(0.5f
, input_vector_
.get(), len
, 0.1f
);
66 double total_time_milliseconds
=
67 (TimeTicks::HighResNow() - start
).InMillisecondsF();
68 perf_test::PrintResult(test_name
,
71 kEWMABenchmarkIterations
/ total_time_milliseconds
,
77 scoped_ptr
<float, base::AlignedFreeDeleter
> input_vector_
;
78 scoped_ptr
<float, base::AlignedFreeDeleter
> output_vector_
;
80 DISALLOW_COPY_AND_ASSIGN(VectorMathPerfTest
);
83 // Define platform independent function name for FMAC* perf tests.
84 #if defined(ARCH_CPU_X86_FAMILY)
85 #define FMAC_FUNC FMAC_SSE
86 #elif defined(ARCH_CPU_ARM_FAMILY) && defined(USE_NEON)
87 #define FMAC_FUNC FMAC_NEON
90 // Benchmark for each optimized vector_math::FMAC() method.
91 TEST_F(VectorMathPerfTest
, FMAC
) {
92 // Benchmark FMAC_C().
94 vector_math::FMAC_C
, true, "vector_math_fmac", "unoptimized");
95 #if defined(FMAC_FUNC)
96 #if defined(ARCH_CPU_X86_FAMILY)
97 ASSERT_TRUE(base::CPU().has_sse());
99 // Benchmark FMAC_FUNC() with unaligned size.
100 ASSERT_NE((kVectorSize
- 1) % (vector_math::kRequiredAlignment
/
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)),
108 vector_math::FMAC_FUNC
, true, "vector_math_fmac", "optimized_aligned");
114 // Define platform independent function name for FMULBenchmark* tests.
115 #if defined(ARCH_CPU_X86_FAMILY)
116 #define FMUL_FUNC FMUL_SSE
117 #elif defined(ARCH_CPU_ARM_FAMILY) && defined(USE_NEON)
118 #define FMUL_FUNC FMUL_NEON
121 // Benchmark for each optimized vector_math::FMUL() method.
122 TEST_F(VectorMathPerfTest
, FMUL
) {
123 // Benchmark FMUL_C().
125 vector_math::FMUL_C
, true, "vector_math_fmul", "unoptimized");
126 #if defined(FMUL_FUNC)
127 #if defined(ARCH_CPU_X86_FAMILY)
128 ASSERT_TRUE(base::CPU().has_sse());
130 // Benchmark FMUL_FUNC() with unaligned size.
131 ASSERT_NE((kVectorSize
- 1) % (vector_math::kRequiredAlignment
/
134 vector_math::FMUL_FUNC
, false, "vector_math_fmul", "optimized_unaligned");
135 // Benchmark FMUL_FUNC() with aligned size.
136 ASSERT_EQ(kVectorSize
% (vector_math::kRequiredAlignment
/ sizeof(float)),
139 vector_math::FMUL_FUNC
, true, "vector_math_fmul", "optimized_aligned");
145 #if defined(ARCH_CPU_X86_FAMILY)
146 #define EWMAAndMaxPower_FUNC EWMAAndMaxPower_SSE
147 #elif defined(ARCH_CPU_ARM_FAMILY) && defined(USE_NEON)
148 #define EWMAAndMaxPower_FUNC EWMAAndMaxPower_NEON
151 // Benchmark for each optimized vector_math::EWMAAndMaxPower() method.
152 TEST_F(VectorMathPerfTest
, EWMAAndMaxPower
) {
153 // Benchmark EWMAAndMaxPower_C().
154 RunBenchmark(vector_math::EWMAAndMaxPower_C
,
156 "vector_math_ewma_and_max_power",
158 #if defined(EWMAAndMaxPower_FUNC)
159 #if defined(ARCH_CPU_X86_FAMILY)
160 ASSERT_TRUE(base::CPU().has_sse());
162 // Benchmark EWMAAndMaxPower_FUNC() with unaligned size.
163 ASSERT_NE((kVectorSize
- 1) % (vector_math::kRequiredAlignment
/
165 RunBenchmark(vector_math::EWMAAndMaxPower_FUNC
,
167 "vector_math_ewma_and_max_power",
168 "optimized_unaligned");
169 // Benchmark EWMAAndMaxPower_FUNC() with aligned size.
170 ASSERT_EQ(kVectorSize
% (vector_math::kRequiredAlignment
/ sizeof(float)),
172 RunBenchmark(vector_math::EWMAAndMaxPower_FUNC
,
174 "vector_math_ewma_and_max_power",
175 "optimized_aligned");
179 #undef EWMAAndMaxPower_FUNC