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.
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"
13 using base::TimeTicks
;
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;
23 class VectorMathPerfTest
: public testing::Test
{
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
);
35 void RunBenchmark(void (*fn
)(const float[], float, int, float[]),
37 const std::string
& test_name
,
38 const std::string
& trace_name
) {
39 TimeTicks start
= TimeTicks::Now();
40 for (int i
= 0; i
< kBenchmarkIterations
; ++i
) {
41 fn(input_vector_
.get(),
43 kVectorSize
- (aligned
? 0 : 1),
44 output_vector_
.get());
46 double total_time_milliseconds
=
47 (TimeTicks::Now() - start
).InMillisecondsF();
48 perf_test::PrintResult(test_name
,
51 kBenchmarkIterations
/ total_time_milliseconds
,
57 std::pair
<float, float> (*fn
)(float, const float[], int, float),
59 const std::string
& test_name
,
60 const std::string
& trace_name
) {
61 TimeTicks start
= TimeTicks::Now();
62 for (int i
= 0; i
< kEWMABenchmarkIterations
; ++i
) {
63 fn(0.5f
, input_vector_
.get(), len
, 0.1f
);
65 double total_time_milliseconds
=
66 (TimeTicks::Now() - start
).InMillisecondsF();
67 perf_test::PrintResult(test_name
,
70 kEWMABenchmarkIterations
/ total_time_milliseconds
,
76 scoped_ptr
<float, base::AlignedFreeDeleter
> input_vector_
;
77 scoped_ptr
<float, base::AlignedFreeDeleter
> output_vector_
;
79 DISALLOW_COPY_AND_ASSIGN(VectorMathPerfTest
);
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
93 // Benchmark for each optimized vector_math::FMAC() method.
94 TEST_F(VectorMathPerfTest
, FMAC
) {
95 // Benchmark FMAC_C().
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
/
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");
112 // Benchmark for each optimized vector_math::FMUL() method.
113 TEST_F(VectorMathPerfTest
, FMUL
) {
114 // Benchmark FMUL_C().
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
/
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)),
127 vector_math::FMUL_FUNC
, true, "vector_math_fmul", "optimized_aligned");
131 // Benchmark for each optimized vector_math::EWMAAndMaxPower() method.
132 TEST_F(VectorMathPerfTest
, EWMAAndMaxPower
) {
133 // Benchmark EWMAAndMaxPower_C().
134 RunBenchmark(vector_math::EWMAAndMaxPower_C
,
136 "vector_math_ewma_and_max_power",
138 #if defined(EWMAAndMaxPower_FUNC)
139 // Benchmark EWMAAndMaxPower_FUNC() with unaligned size.
140 ASSERT_NE((kVectorSize
- 1) % (vector_math::kRequiredAlignment
/
142 RunBenchmark(vector_math::EWMAAndMaxPower_FUNC
,
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)),
149 RunBenchmark(vector_math::EWMAAndMaxPower_FUNC
,
151 "vector_math_ewma_and_max_power",
152 "optimized_aligned");