Branch hints in frequently used inlines

Former-commit-id: aff247930de71d535e5cb455828f993b244053a2
This commit is contained in:
Marek Nečada 2019-08-17 11:58:10 +03:00
parent 3e427f35ae
commit 7b8e7d39e5
3 changed files with 44 additions and 18 deletions

View File

@ -6,6 +6,7 @@
#include "qpms_types.h" #include "qpms_types.h"
#include <math.h> #include <math.h>
#include "optim.h"
@ -72,8 +73,8 @@ static inline qpms_errno_t qpms_uvswfi2tmn(qpms_uvswfi_t u,
qpms_y_sc_t y_sc = u / 4; qpms_y_sc_t y_sc = u / 4;
qpms_y2mn_sc_p(y_sc, m, n); qpms_y2mn_sc_p(y_sc, m, n);
// Test validity // Test validity
if (*t == 3) return QPMS_ERROR; // VSWF type code invalid, TODO WARN if (QPMS_UNLIKELY(*t == 3)) return QPMS_ERROR; // VSWF type code invalid, TODO WARN
if (*t && !y_sc) return QPMS_ERROR; // l == 0 for transversal wave, TODO WARN if (QPMS_UNLIKELY(*t && !y_sc)) return QPMS_ERROR; // l == 0 for transversal wave, TODO WARN
return QPMS_SUCCESS; return QPMS_SUCCESS;
} }
@ -83,8 +84,8 @@ static inline qpms_errno_t qpms_uvswfi2ty(qpms_uvswfi_t u,
qpms_vswf_type_t *t, qpms_y_t *y) { qpms_vswf_type_t *t, qpms_y_t *y) {
*t = u & 3; *t = u & 3;
*y = u / 4 - 1; *y = u / 4 - 1;
if (*t == 0 || *t == 3) return QPMS_ERROR; if (QPMS_UNLIKELY(*t == 0 || *t == 3)) return QPMS_ERROR;
if (*y < 0) return QPMS_ERROR; if (QPMS_UNLIKELY(*y < 0)) return QPMS_ERROR;
return QPMS_SUCCESS; return QPMS_SUCCESS;
} }
@ -96,8 +97,8 @@ static inline qpms_errno_t qpms_uvswfi2ty_l(qpms_uvswfi_t u,
qpms_vswf_type_t *t, qpms_y_t *y) { qpms_vswf_type_t *t, qpms_y_t *y) {
*t = u & 3; *t = u & 3;
*y = u / 4 - 1; *y = u / 4 - 1;
if (*t == 3) return QPMS_ERROR; if (QPMS_UNLIKELY(*t == 3)) return QPMS_ERROR;
if (*y < 0) return QPMS_ERROR; if (QPMS_UNLIKELY(*y < 0)) return QPMS_ERROR;
return QPMS_SUCCESS; return QPMS_SUCCESS;
} }

View File

@ -11,11 +11,12 @@
#include <math.h> #include <math.h>
#include <complex.h> #include <complex.h>
#include "indexing.h" #include "indexing.h"
#include "optim.h"
/// Returns the (real positive) common norm factor of a given normalisation compared to the reference convention. /// Returns the (real positive) common norm factor of a given normalisation compared to the reference convention.
/** Does NOT perform the inversion if QPMS_NORMALISATION_INVERSE is set. */ /** Does NOT perform the inversion if QPMS_NORMALISATION_INVERSE is set. */
static inline double qpms_normalisation_normfactor(qpms_normalisation_t norm, qpms_l_t l, qpms_m_t m) { static inline double qpms_normalisation_normfactor(qpms_normalisation_t norm, qpms_l_t l, qpms_m_t m) {
switch (norm & QPMS_NORMALISATION_NORM_BITS) { switch (QPMS_EXPECT(norm & QPMS_NORMALISATION_NORM_BITS, norm & QPMS_NORMALISATION_DEFAULT)) {
case QPMS_NORMALISATION_NORM_POWER: case QPMS_NORMALISATION_NORM_POWER:
return 1; return 1;
case QPMS_NORMALISATION_NORM_SPHARM: case QPMS_NORMALISATION_NORM_SPHARM:
@ -37,9 +38,9 @@ static inline double qpms_normalisation_normfactor(qpms_normalisation_t norm, qp
*/ */
static inline complex double qpms_normalisation_factor_M_noCS(qpms_normalisation_t norm, qpms_l_t l, qpms_m_t m) { static inline complex double qpms_normalisation_factor_M_noCS(qpms_normalisation_t norm, qpms_l_t l, qpms_m_t m) {
complex double fac = qpms_normalisation_normfactor(norm, l, m); complex double fac = qpms_normalisation_normfactor(norm, l, m);
if (norm & QPMS_NORMALISATION_M_MINUS) fac *= -1; if (QPMS_UNLIKELY(norm & QPMS_NORMALISATION_M_MINUS)) fac *= -1;
if (norm & QPMS_NORMALISATION_M_I) fac *= I; if (QPMS_UNLIKELY(norm & QPMS_NORMALISATION_M_I)) fac *= I;
if (norm & QPMS_NORMALISATION_INVERSE) fac = 1/fac; if (QPMS_UNLIKELY(norm & QPMS_NORMALISATION_INVERSE)) fac = 1/fac;
return fac; return fac;
} }
@ -63,9 +64,9 @@ static inline complex double qpms_normalisation_factor_M(qpms_normalisation_t no
*/ */
static inline complex double qpms_normalisation_factor_N_noCS(qpms_normalisation_t norm, qpms_l_t l, qpms_m_t m) { static inline complex double qpms_normalisation_factor_N_noCS(qpms_normalisation_t norm, qpms_l_t l, qpms_m_t m) {
complex double fac = qpms_normalisation_normfactor(norm, l, m); complex double fac = qpms_normalisation_normfactor(norm, l, m);
if (norm & QPMS_NORMALISATION_N_MINUS) fac *= -1; if (QPMS_UNLIKELY(norm & QPMS_NORMALISATION_N_MINUS)) fac *= -1;
if (norm & QPMS_NORMALISATION_N_I) fac *= I; if (QPMS_UNLIKELY(norm & QPMS_NORMALISATION_N_I)) fac *= I;
if (norm & QPMS_NORMALISATION_INVERSE) fac = 1/fac; if (QPMS_UNLIKELY(norm & QPMS_NORMALISATION_INVERSE)) fac = 1/fac;
return fac; return fac;
} }
@ -96,9 +97,9 @@ static inline complex double qpms_normalisation_factor_N_M(qpms_normalisation_t
*/ */
static inline complex double qpms_normalisation_factor_L_noCS(qpms_normalisation_t norm, qpms_l_t l, qpms_m_t m) { static inline complex double qpms_normalisation_factor_L_noCS(qpms_normalisation_t norm, qpms_l_t l, qpms_m_t m) {
complex double fac = qpms_normalisation_normfactor(norm, l, m); complex double fac = qpms_normalisation_normfactor(norm, l, m);
if (norm & QPMS_NORMALISATION_L_MINUS) fac *= -1; if (QPMS_UNLIKELY(norm & QPMS_NORMALISATION_L_MINUS)) fac *= -1;
if (norm & QPMS_NORMALISATION_L_I) fac *= I; if (QPMS_UNLIKELY(norm & QPMS_NORMALISATION_L_I)) fac *= I;
if (norm & QPMS_NORMALISATION_INVERSE) fac = 1/fac; if (QPMS_UNLIKELY(norm & QPMS_NORMALISATION_INVERSE)) fac = 1/fac;
return fac; return fac;
} }
@ -156,7 +157,8 @@ static inline qpms_normalisation_t qpms_normalisation_dual(qpms_normalisation_t
* \f] * \f]
*/ */
static inline complex double qpms_spharm_azimuthal_part(qpms_normalisation_t norm, qpms_m_t m, double phi) { static inline complex double qpms_spharm_azimuthal_part(qpms_normalisation_t norm, qpms_m_t m, double phi) {
switch(norm & (QPMS_NORMALISATION_REVERSE_AZIMUTHAL_PHASE | QPMS_NORMALISATION_SPHARM_REAL)) { switch(QPMS_EXPECT(norm, QPMS_NORMALISATION_DEFAULT)
& (QPMS_NORMALISATION_REVERSE_AZIMUTHAL_PHASE | QPMS_NORMALISATION_SPHARM_REAL)) {
case 0: case 0:
return cexp(I*m*phi); return cexp(I*m*phi);
case QPMS_NORMALISATION_REVERSE_AZIMUTHAL_PHASE: case QPMS_NORMALISATION_REVERSE_AZIMUTHAL_PHASE:
@ -194,7 +196,8 @@ static inline complex double qpms_spharm_azimuthal_part(qpms_normalisation_t nor
*/ */
static inline complex double qpms_spharm_azimuthal_part_derivative_div_m(qpms_normalisation_t norm, qpms_m_t m, double phi) { static inline complex double qpms_spharm_azimuthal_part_derivative_div_m(qpms_normalisation_t norm, qpms_m_t m, double phi) {
if(m==0) return 0; if(m==0) return 0;
switch(norm & (QPMS_NORMALISATION_REVERSE_AZIMUTHAL_PHASE | QPMS_NORMALISATION_SPHARM_REAL)) { switch(QPMS_EXPECT(norm, QPMS_NORMALISATION_DEFAULT)
& (QPMS_NORMALISATION_REVERSE_AZIMUTHAL_PHASE | QPMS_NORMALISATION_SPHARM_REAL)) {
case 0: case 0:
return I*cexp(I*m*phi); return I*cexp(I*m*phi);
case QPMS_NORMALISATION_REVERSE_AZIMUTHAL_PHASE: case QPMS_NORMALISATION_REVERSE_AZIMUTHAL_PHASE:

22
qpms/optim.h Normal file
View File

@ -0,0 +1,22 @@
/** \file optim.h
* \brief Macros for compiler optimisation.
*/
#ifndef QPMS_OPTIM_H
#define QPMS_OPTIM_H
#if ((defined __GNUC__) || (defined __clang__)) && !(defined QPMS_NO_BUILTIN_EXPECT)
/// Wrapper over gcc's and clang's __builtin_expect.
/** If expands to __builtin_expect if gcc or clang are used,
* else expands only to the first argument.
*/
#define QPMS_EXPECT(exp, c) __builtin_expect(exp, c)
#define QPMS_LIKELY(x) __builtin_expect(!!(x), 1)
#define QPMS_UNLIKELY(x) __builtin_expect(!!(x), 0)
#else
#define QPMS_LIKELY(x) (x)
#define QPMS_UNLIKELY(x)
#define QPMS_EXPECT(exp,c) (exp)
#endif
#endif // OPTIM_H