1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
| static void fill_random_value(std::vector<float>& vec_data) { std::uniform_real_distribution<float> distribution( std::numeric_limits<float>::min(), std::numeric_limits<float>::max()); std::default_random_engine generator;
std::generate(vec_data.begin(), vec_data.end(), [&]() { return distribution(generator); }); }
static bool is_equals_vector(const std::vector<float>& vec_a, const std::vector<float>& vec_b) { if (vec_a.size() != vec_b.size()) { return false; } for (size_t i = 0; i < vec_a.size(); i++) { if (vec_a[i] != vec_b[i]) { return false; } } return true; }
static void normal_vector_mul(const std::vector<float>& vec_a, const std::vector<float>& vec_b, std::vector<float>& vec_result) { assert(vec_a.size() == vec_b.size()); assert(vec_a.size() == vec_result.size()); for (size_t i = 0; i < vec_result.size();i++) { vec_result[i] = vec_a[i] * vec_b[i]; } }
static void neon_vector_mul(const std::vector<float>& vec_a, const std::vector<float>& vec_b, std::vector<float>& vec_result) { assert(vec_a.size() == vec_b.size()); assert(vec_a.size() == vec_result.size()); int i = 0; for (; i < (int)vec_result.size() - 3 ; i+=4) { const auto data_a = vld1q_f32(&vec_a[i]); const auto data_b = vld1q_f32(&vec_b[i]); float* dst_ptr = &vec_result[i]; const auto data_res = vmulq_f32(data_a, data_b); vst1q_f32(dst_ptr, data_res); } for (; i < (int)vec_result.size(); i++) { vec_result[i] = vec_a[i] * vec_b[i]; } }
static int test_neon() { const int test_round = 1000; const int data_len = 10000; std::vector<float> vec_a(data_len); std::vector<float> vec_b(data_len); std::vector<float> vec_result(data_len); std::vector<float> vec_result2(data_len); fill_random_value(vec_a); fill_random_value(vec_b); { normal_vector_mul(vec_a, vec_b, vec_result); neon_vector_mul(vec_a, vec_b, vec_result2); if (!is_equals_vector(vec_result,vec_result2)) { std::cerr << "result vector is not equals!" << std::endl; return -1; } } { FuncCostTimeHelper time_helper("normal_vector_mul"); for (int i = 0; i < test_round;i++) { normal_vector_mul(vec_a, vec_b, vec_result); } } { FuncCostTimeHelper time_helper("neon_vector_mul"); for (int i = 0; i < test_round; i++) { neon_vector_mul(vec_a, vec_b, vec_result2); } } return 0; }
int main(int, char*[]) { return test_neon(); }
|