commit 9669a81f1601729e5580b9b57b83284fa270fd6a
parent 594bb23b98d8c94b7e4892abfb813e505185cd88
Author: David Freifeld <freifeld.david@gmail.com>
Date: Thu, 30 Jul 2020 17:15:40 -0700
More investigating cwise functions
Diffstat:
2 files changed, 36 insertions(+), 9 deletions(-)
diff --git a/src/utils.cpp b/src/utils.cpp
@@ -23,7 +23,7 @@
// Yes, these functions may be a frustrating to read but they're just equations and I want to conserve space.
float sigmoid(float x) {return 1.0/(1+exp(-x));}
-float sigmoid_deriv(float x) {return 1.0/(1+exp(-x)) * (1 - 1.0/(1+exp(x)));}
+float sigmoid_deriv(float x) {return 1.0/(1+exp(-x)) * (1 - 1.0/(1+exp(-x)));}
float linear(float x) {return x;}
float linear_deriv(float x) {return 1;}
diff --git a/tests/simd.cpp b/tests/simd.cpp
@@ -3,19 +3,46 @@
#include <iostream>
#include <cmath>
+float sigmoid(float x) {return 1.0/(1+exp(-x));}
+float sigmoid_deriv(float x) {return 1.0/(1+exp(-x)) * (1 - 1.0/(1+exp(-x)));}
+
int main()
{
- Eigen::MatrixXf a = Eigen::MatrixXf::Random(1000, 1000);
+ int sz;
+ std::cin >> sz;
+ Eigen::MatrixXf a = Eigen::MatrixXf::Random(sz, sz);
- auto simd_start = std::chrono::high_resolution_clock::now();
- a.array().exp().matrix();
- auto simd_end = std::chrono::high_resolution_clock::now();
- auto start = std::chrono::high_resolution_clock::now();
+ auto sigmoid_simd_start = std::chrono::high_resolution_clock::now();
+ Eigen::MatrixXf a1 = (1 + (-1 * a.array()).exp()).pow(-1).matrix();
+ auto sigmoid_simd_end = std::chrono::high_resolution_clock::now();
+ auto sigmoid_start = std::chrono::high_resolution_clock::now();
+ Eigen::MatrixXf a2 (a.rows(), a.cols());
for (int i = 0; i < a.rows(); i++) {
for (int j = 0; j < a.cols(); j++) {
- a(i,j) = exp(a(i,j));
+ a2(i,j) = sigmoid(a(i,j));
}
}
- auto end = std::chrono::high_resolution_clock::now();
- std::cout << "SIMD: " << std::chrono::duration_cast<std::chrono::nanoseconds>(simd_end - simd_start).count() << " NORMAL: " << std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count() << "\n";
+ auto sigmoid_end = std::chrono::high_resolution_clock::now();
+ if (a1.isApprox(a2)) std::cout << "Sigmoid matrices are equal!\n\n";
+
+ auto sigmoid_deriv_simd_start = std::chrono::high_resolution_clock::now();
+ Eigen::MatrixXf ones = Eigen::MatrixXf::Ones(a.rows(), a.cols());
+ Eigen::MatrixXf deriv_a1 = (1 + (-1 * a.array()).exp()).pow(-1).matrix().cwiseProduct(ones-(1 + (-1 * a.array()).exp()).pow(-1).matrix());
+ auto sigmoid_deriv_simd_end = std::chrono::high_resolution_clock::now();
+ auto sigmoid_deriv_start = std::chrono::high_resolution_clock::now();
+ Eigen::MatrixXf deriv_a2 (a.rows(), a.cols());
+ for (int i = 0; i < a.rows(); i++) {
+ for (int j = 0; j < a.cols(); j++) {
+ deriv_a2(i,j) = sigmoid_deriv(a(i,j));
+ }
+ }
+ auto sigmoid_deriv_end = std::chrono::high_resolution_clock::now();
+ if (deriv_a1.isApprox(deriv_a2)) std::cout << "Sigmoid derivative matrices are equal!\n\n";
+
+ double eigen_time = std::chrono::duration_cast<std::chrono::nanoseconds>(sigmoid_simd_end - sigmoid_simd_start).count();
+ double normal_time = std::chrono::duration_cast<std::chrono::nanoseconds>(sigmoid_end - sigmoid_start).count();
+ double eigen_deriv_time = std::chrono::duration_cast<std::chrono::nanoseconds>(sigmoid_deriv_simd_end - sigmoid_deriv_simd_start).count();
+ double normal_deriv_time = std::chrono::duration_cast<std::chrono::nanoseconds>(sigmoid_deriv_end - sigmoid_deriv_start).count();
+ std::cout << "SIGMOID:\n\tEIGEN FUNCTIONS (SOME SIMD): " << eigen_time << "\n\tNORMAL ITERATIVE METHOD: " << normal_time << "\n\tSPEEDUP FACTOR: " << normal_time/eigen_time << "\n";
+ std::cout << "SIGMOID DERIVATIVE:\n\tEIGEN FUNCTIONS (SOME SIMD): " << eigen_deriv_time << "\n\tNORMAL ITERATIVE METHOD: " << normal_deriv_time << "\n\tSPEEDUP FACTOR: " << normal_deriv_time/eigen_deriv_time << "\n";
}