From 85291627a4ed14329a372d6b327fb20945fd5965 Mon Sep 17 00:00:00 2001 From: Mahesh Madhav Date: Tue, 3 Sep 2024 07:17:25 +0000 Subject: [PATCH 1/5] Optimize computation in GrowthCurveGaussian Replace FP divides with FP multiplies. Pre-compute constants. --- nestkernel/growth_curve.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/nestkernel/growth_curve.cpp b/nestkernel/growth_curve.cpp index c26c0e5e11..32af8aab03 100644 --- a/nestkernel/growth_curve.cpp +++ b/nestkernel/growth_curve.cpp @@ -32,6 +32,9 @@ // Includes from sli: #include "dictutils.h" +// 1.0 / (2.0 * sqrt( log( 2.0 ) )) +#define INV_TWO_SQRT_LOG_TWO 0.6005612043932248974 + /* ---------------------------------------------------------------- * GrowthCurveLinear * ---------------------------------------------------------------- */ @@ -106,16 +109,17 @@ nest::GrowthCurveGaussian::update( double t, // Numerical integration from t_minus to t // use standard forward Euler numerics const double h = Time::get_resolution().get_ms(); - const double zeta = ( eta_ - eps_ ) / ( 2.0 * sqrt( log( 2.0 ) ) ); - const double xi = ( eta_ + eps_ ) / 2.0; + const double inv_zeta = ( eta_ - eps_ ) * INV_TWO_SQRT_LOG_TWO; + const double xi = ( eta_ + eps_ ) * 0.5; + const double inv_tau_Ca = 1.0 / tau_Ca; double z_value = z_minus; double Ca = Ca_minus; - for ( double lag = t_minus; lag < ( t - h / 2.0 ); lag += h ) + for ( double lag = t_minus; lag < ( t - h * 0.5 ); lag += h ) { - Ca = Ca - ( ( Ca / tau_Ca ) * h ); - const double dz = h * growth_rate * ( 2.0 * exp( -pow( ( Ca - xi ) / zeta, 2 ) ) - 1.0 ); + Ca = Ca - ( ( Ca * inv_tau_Ca ) * h ); + const double dz = h * growth_rate * ( 2.0 * exp( -pow( ( Ca - xi ) * inv_zeta, 2 ) ) - 1.0 ); z_value = z_value + dz; } From aee65c954785e0879a3da73c5fee5c8ab1edeb95 Mon Sep 17 00:00:00 2001 From: Mahesh Madhav Date: Tue, 3 Sep 2024 19:30:10 +0000 Subject: [PATCH 2/5] Pre-compute and store local variables --- libnestutil/numerics.cpp | 2 ++ libnestutil/numerics.h | 1 + nestkernel/growth_curve.cpp | 12 +++++++++--- nestkernel/growth_curve.h | 4 ++++ 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/libnestutil/numerics.cpp b/libnestutil/numerics.cpp index 412a5fadd4..088dfb8068 100644 --- a/libnestutil/numerics.cpp +++ b/libnestutil/numerics.cpp @@ -93,6 +93,8 @@ const double numerics::nan = NAN; const double numerics::nan = 0.0 / 0.0; #endif +const double numerics::sqrt_log_two = std::sqrt( std::log( 2.0 ) ); + // later also in namespace long ld_round( double x ) diff --git a/libnestutil/numerics.h b/libnestutil/numerics.h index a4c077ffe6..baa7666c42 100644 --- a/libnestutil/numerics.h +++ b/libnestutil/numerics.h @@ -47,6 +47,7 @@ namespace numerics extern const double e; extern const double pi; extern const double nan; +extern const double sqrt_log_two; /** Supply expm1() function independent of system. * @note Implemented inline for efficiency. diff --git a/nestkernel/growth_curve.cpp b/nestkernel/growth_curve.cpp index 32af8aab03..07d1aa5b46 100644 --- a/nestkernel/growth_curve.cpp +++ b/nestkernel/growth_curve.cpp @@ -32,9 +32,6 @@ // Includes from sli: #include "dictutils.h" -// 1.0 / (2.0 * sqrt( log( 2.0 ) )) -#define INV_TWO_SQRT_LOG_TWO 0.6005612043932248974 - /* ---------------------------------------------------------------- * GrowthCurveLinear * ---------------------------------------------------------------- */ @@ -81,6 +78,7 @@ nest::GrowthCurveGaussian::GrowthCurveGaussian() , eta_( 0.1 ) , eps_( 0.7 ) { + compute_local(); } void @@ -96,6 +94,7 @@ nest::GrowthCurveGaussian::set( const DictionaryDatum& d ) { updateValue< double >( d, names::eps, eps_ ); updateValue< double >( d, names::eta, eta_ ); + compute_local(); } double @@ -126,6 +125,13 @@ nest::GrowthCurveGaussian::update( double t, return std::max( z_value, 0.0 ); } +void +nest::GrowthCurveGaussian::compute_local() +{ + inv_zeta_ = 2.0 * numerics::sqrt_log_two / ( eta_ - eps_ ); + xi_ = ( eta_ + eps_ ) * 0.5; +} + /* ---------------------------------------------------------------- * GrowthCurveSigmoid * ---------------------------------------------------------------- */ diff --git a/nestkernel/growth_curve.h b/nestkernel/growth_curve.h index 10a350224e..ee32bc297c 100644 --- a/nestkernel/growth_curve.h +++ b/nestkernel/growth_curve.h @@ -227,8 +227,12 @@ class GrowthCurveGaussian : public GrowthCurve update( double t, double t_minus, double Ca_minus, double z, double tau_Ca, double growth_rate ) const override; private: + void compute_local(); + double eta_; double eps_; + double inv_zeta_; + double xi_; }; /** @BeginDocumentation From eec68a502c80ae7085e93066cb1e2c5823b597fa Mon Sep 17 00:00:00 2001 From: Mahesh Madhav <67384846+heshpdx@users.noreply.github.com> Date: Tue, 3 Sep 2024 12:34:41 -0700 Subject: [PATCH 3/5] Apply suggestions from code review Co-authored-by: Hans Ekkehard Plesser --- nestkernel/growth_curve.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nestkernel/growth_curve.cpp b/nestkernel/growth_curve.cpp index 07d1aa5b46..e2e3708223 100644 --- a/nestkernel/growth_curve.cpp +++ b/nestkernel/growth_curve.cpp @@ -118,8 +118,8 @@ nest::GrowthCurveGaussian::update( double t, for ( double lag = t_minus; lag < ( t - h * 0.5 ); lag += h ) { Ca = Ca - ( ( Ca * inv_tau_Ca ) * h ); - const double dz = h * growth_rate * ( 2.0 * exp( -pow( ( Ca - xi ) * inv_zeta, 2 ) ) - 1.0 ); - z_value = z_value + dz; + const double dz = h * growth_rate * ( 2.0 * std::exp( -std::pow( ( Ca - xi ) * inv_zeta, 2 ) ) - 1.0 ); + z_value += dz; } return std::max( z_value, 0.0 ); From 47ef5ca26ae3814b0f21d5ec53e9d17b8e87b70d Mon Sep 17 00:00:00 2001 From: Mahesh Madhav Date: Tue, 3 Sep 2024 19:40:44 +0000 Subject: [PATCH 4/5] Switch to using precomputed local variables --- nestkernel/growth_curve.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/nestkernel/growth_curve.cpp b/nestkernel/growth_curve.cpp index e2e3708223..e73a0413b5 100644 --- a/nestkernel/growth_curve.cpp +++ b/nestkernel/growth_curve.cpp @@ -108,8 +108,6 @@ nest::GrowthCurveGaussian::update( double t, // Numerical integration from t_minus to t // use standard forward Euler numerics const double h = Time::get_resolution().get_ms(); - const double inv_zeta = ( eta_ - eps_ ) * INV_TWO_SQRT_LOG_TWO; - const double xi = ( eta_ + eps_ ) * 0.5; const double inv_tau_Ca = 1.0 / tau_Ca; double z_value = z_minus; @@ -118,7 +116,7 @@ nest::GrowthCurveGaussian::update( double t, for ( double lag = t_minus; lag < ( t - h * 0.5 ); lag += h ) { Ca = Ca - ( ( Ca * inv_tau_Ca ) * h ); - const double dz = h * growth_rate * ( 2.0 * std::exp( -std::pow( ( Ca - xi ) * inv_zeta, 2 ) ) - 1.0 ); + const double dz = h * growth_rate * ( 2.0 * std::exp( -std::pow( ( Ca - xi_ ) * inv_zeta_, 2 ) ) - 1.0 ); z_value += dz; } From 2a8c7f8228468f5a2edbf73c43c1110599a79f21 Mon Sep 17 00:00:00 2001 From: Mahesh Madhav <67384846+heshpdx@users.noreply.github.com> Date: Tue, 3 Sep 2024 12:46:10 -0700 Subject: [PATCH 5/5] Apply suggestions from code review Co-authored-by: Hans Ekkehard Plesser --- nestkernel/growth_curve.cpp | 6 +++--- nestkernel/growth_curve.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/nestkernel/growth_curve.cpp b/nestkernel/growth_curve.cpp index e73a0413b5..549d7d98bc 100644 --- a/nestkernel/growth_curve.cpp +++ b/nestkernel/growth_curve.cpp @@ -78,7 +78,7 @@ nest::GrowthCurveGaussian::GrowthCurveGaussian() , eta_( 0.1 ) , eps_( 0.7 ) { - compute_local(); + compute_local_(); } void @@ -94,7 +94,7 @@ nest::GrowthCurveGaussian::set( const DictionaryDatum& d ) { updateValue< double >( d, names::eps, eps_ ); updateValue< double >( d, names::eta, eta_ ); - compute_local(); + compute_local_(); } double @@ -124,7 +124,7 @@ nest::GrowthCurveGaussian::update( double t, } void -nest::GrowthCurveGaussian::compute_local() +nest::GrowthCurveGaussian::compute_local_() { inv_zeta_ = 2.0 * numerics::sqrt_log_two / ( eta_ - eps_ ); xi_ = ( eta_ + eps_ ) * 0.5; diff --git a/nestkernel/growth_curve.h b/nestkernel/growth_curve.h index ee32bc297c..1d4b03b148 100644 --- a/nestkernel/growth_curve.h +++ b/nestkernel/growth_curve.h @@ -227,7 +227,7 @@ class GrowthCurveGaussian : public GrowthCurve update( double t, double t_minus, double Ca_minus, double z, double tau_Ca, double growth_rate ) const override; private: - void compute_local(); + void compute_local_(); double eta_; double eps_;