/* Calculate exponentials through SIMD */ gmx_inline static void calc_exponentials_lj(int gmx_unused start, int end, real *r_aligned, real *factor_aligned, real *d_aligned) { gmx_simd_real_t tmp_r, tmp_d, tmp_fac, d_inv, tmp_mk; const gmx_simd_real_t sqr_PI = gmx_simd_sqrt_r(gmx_simd_set1_r(M_PI)); int kx; for (kx = 0; kx < end; kx += GMX_SIMD_REAL_WIDTH) { /* We only need to calculate from start. But since start is 0 or 1 * and we want to use aligned loads/stores, we always start from 0. */ tmp_d = gmx_simd_load_r(d_aligned+kx); d_inv = gmx_simd_inv_r(tmp_d); gmx_simd_store_r(d_aligned+kx, d_inv); tmp_r = gmx_simd_load_r(r_aligned+kx); tmp_r = gmx_simd_exp_r(tmp_r); gmx_simd_store_r(r_aligned+kx, tmp_r); tmp_mk = gmx_simd_load_r(factor_aligned+kx); tmp_fac = gmx_simd_mul_r(sqr_PI, gmx_simd_mul_r(tmp_mk, gmx_simd_erfc_r(tmp_mk))); gmx_simd_store_r(factor_aligned+kx, tmp_fac); } }
gmx_simd_real_t vector2SimdReal(const std::vector<real> &v) { real mem[GMX_SIMD_REAL_WIDTH*2]; real * p = gmx_simd_align_r(mem); for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++) { p[i] = v[i % v.size()]; // repeat vector contents to fill simd width } return gmx_simd_load_r(p); }
/* Calculate exponentials through SIMD */ gmx_inline static void calc_exponentials_q(int gmx_unused start, int end, real f, real *d_aligned, real *r_aligned, real *e_aligned) { { gmx_simd_real_t f_simd; gmx_simd_real_t tmp_d1, d_inv, tmp_r, tmp_e; int kx; f_simd = gmx_simd_set1_r(f); /* We only need to calculate from start. But since start is 0 or 1 * and we want to use aligned loads/stores, we always start from 0. */ for (kx = 0; kx < end; kx += GMX_SIMD_REAL_WIDTH) { tmp_d1 = gmx_simd_load_r(d_aligned+kx); d_inv = gmx_simd_inv_r(tmp_d1); tmp_r = gmx_simd_load_r(r_aligned+kx); tmp_r = gmx_simd_exp_r(tmp_r); tmp_e = gmx_simd_mul_r(f_simd, d_inv); tmp_e = gmx_simd_mul_r(tmp_e, tmp_r); gmx_simd_store_r(e_aligned+kx, tmp_e); } } }