ppc_altivec_util.h
来自「最著名最快的分子模拟软件」· C头文件 代码 · 共 1,756 行 · 第 1/5 页
H
1,756 行
vector float vdata){ vector float tmp; tmp = vec_sld(vdata,vdata,8); vdata = vec_add(vdata,tmp); tmp = vec_sld(vdata,vdata,4); vdata = vec_add(vdata,tmp); tmp = vec_lde(0,address); /* all four positions in vdata contain the sum */ tmp = vec_add(tmp,vdata); vec_ste(tmp,0,address);}/** Load coords of a 3-atom water (9 floats) to all elements in SIMD vectors. * * We use our knowledge about water to improve the loading performance. * The allocated memory is always 8-byte aligned, so with nine atoms * we can always read 3 16-byte chunks (rounded down by vec_ld) * without going outside the current page (which might incur a page fault). * The extra elements before and after the water dont matter as long as we dont * try to write to them. * * @param address Address of first coord in water (oxygen x). * @param shiftvec Address of shift vector x/y/z triplet to add to * all atom coordinates. * @param Ox Output: Oxygen x coordinate in all elements. * @param Oy Output: Oxygen y coordinate in all elements. * @param Oz Output: Oxygen z coordinate in all elements. * @param H1x Output: First hydrogen x coordinate in all elements. * @param H1y Output: First hydrogen y coordinate in all elements. * @param H1z Output: First hydrogen z coordinate in all elements. * @param H2x Output: Second hydrogen x coordinate in all elements. * @param H2y Output: Second hydrogen y coordinate in all elements. * @param H2z Output: Second hydrogen z coordinate in all elements. */static inline void load_1_3atoms_shift_and_splat(float *address, float *shiftvec, vector float *Ox, vector float *Oy, vector float *Oz, vector float *H1x, vector float *H1y, vector float *H1z, vector float *H2x, vector float *H2y, vector float *H2z){ vector unsigned char perm; vector float c1,c2,c3,sha,shb,sh1,sh2,sh3; /* load shift */ shb = load_xyz(shiftvec); /* [ shX shY shZ -] */ /* load the coordinates */ perm = vec_lvsl( 0, (int *) address ); c1 = vec_ld( 0, address ); c2 = vec_ld( 16, address ); c3 = vec_ld( 32, address ); sha = vec_sld(shb,shb,12); /* [ - shX shY shZ ] */ sh1 = vec_sld(sha,shb,4); /* [ shX shY shZ shX ] */ sh2 = vec_sld(sha,shb,8); /* [ shY shZ shX shY ] */ sh3 = vec_sld(sha,shb,12); /* [ shZ shX shY shZ ] */ c1 = vec_perm(c1,c2,perm); /* Ox Oy Oz H1x */ c2 = vec_perm(c2,c3,perm); /* H1y H1z H2x H2y */ c3 = vec_perm(c3,c3,perm); /* H2z - - - */ c1 = vec_add(c1,sh1); c2 = vec_add(c2,sh2); c3 = vec_add(c3,sh3); *Ox = vec_splat(c1,0); *Oy = vec_splat(c1,1); *Oz = vec_splat(c1,2); *H1x = vec_splat(c1,3); *H1y = vec_splat(c2,0); *H1z = vec_splat(c2,1); *H2x = vec_splat(c2,2); *H2y = vec_splat(c2,3); *H2z = vec_splat(c3,0);}/** Load coords of a 4-atom water (12 floats) to all elements in SIMD vectors.** We use our knowledge about water to improve the loading performance.* The allocated memory is always 8-byte aligned, so with twelve atoms* we can always read 4 16-byte chunks (rounded down by vec_ld)* without going outside the current page (which might incur a page fault). * The extra elements before and after the water dont matter as long as we dont* try to write to them.** @param address Address of first coord in 4-atom water (oxygen x).* @param shiftvec Address of shift vector x/y/z triplet to add to* all atom coordinates.* @param Ox Output: Oxygen x coordinate in all elements.* @param Oy Output: Oxygen y coordinate in all elements.* @param Oz Output: Oxygen z coordinate in all elements.* @param H1x Output: First hydrogen x coordinate in all elements.* @param H1y Output: First hydrogen y coordinate in all elements.* @param H1z Output: First hydrogen z coordinate in all elements.* @param H2x Output: Second hydrogen x coordinate in all elements.* @param H2y Output: Second hydrogen y coordinate in all elements.* @param H2z Output: Second hydrogen z coordinate in all elements.* @param Mx Output: Virtual site x coordinate in all elements.* @param My Output: Virtual site y coordinate in all elements.* @param Mz Output: Virtual site z coordinate in all elements.*/static inline void load_1_4atoms_shift_and_splat(float *address, float *shiftvec, vector float *Ox, vector float *Oy, vector float *Oz, vector float *H1x, vector float *H1y, vector float *H1z, vector float *H2x, vector float *H2y, vector float *H2z, vector float *Mx, vector float *My, vector float *Mz){ vector unsigned char perm; vector float c1,c2,c3,c4,sha,shb,sh1,sh2,sh3; /* load shift data */ shb = load_xyz(shiftvec); /* [ shX shY shZ -] */ /* load the coordinates. */ c1 = vec_ld( 0, address ); c2 = vec_ld( 16, address ); c3 = vec_ld( 32, address ); if(((unsigned int)address) & 0xf) { /* Load extra data and rotate if not aligned */ c4 = vec_ld( 48, address ); perm = vec_lvsl( 0, (int *) address ); c1 = vec_perm(c1,c2,perm); /* Ox Oy Oz H1x */ c2 = vec_perm(c2,c3,perm); /* H1y H1z H2x H2y */ c3 = vec_perm(c3,c4,perm); /* H2z Mx My Mz */ } sha = vec_sld(shb,shb,12); /* [ - shX shY shZ ] */ sh1 = vec_sld(sha,shb,4); /* [ shX shY shZ shX ] */ sh2 = vec_sld(sha,shb,8); /* [ shY shZ shX shY ] */ sh3 = vec_sld(sha,shb,12); /* [ shZ shX shY shZ ] */ c1 = vec_add(c1,sh1); c2 = vec_add(c2,sh2); c3 = vec_add(c3,sh3); *Ox = vec_splat(c1,0); *Oy = vec_splat(c1,1); *Oz = vec_splat(c1,2); *H1x = vec_splat(c1,3); *H1y = vec_splat(c2,0); *H1z = vec_splat(c2,1); *H2x = vec_splat(c2,2); *H2y = vec_splat(c2,3); *H2z = vec_splat(c3,0); *Mx = vec_splat(c3,1); *My = vec_splat(c3,2); *Mz = vec_splat(c3,3);}/** Load coords of 4 3-atom waters (4*9 floats) to SIMD vectors.** We use our knowledge about water to improve the loading performance.* The allocated memory is always 8-byte aligned, so with nine atoms* we can always read 3 16-byte chunks (rounded down by vec_ld)* without going outside the current page (which might incur a page fault). * The extra elements before and after the water dont matter as long as we dont* try to write to them.** @param address1 Address of first coord in first water (oxygen x).* @param address2 Address of first coord in second water (oxygen x).* @param address3 Address of first coord in third water (oxygen x).* @param address4 Address of first coord in fourth water (oxygen x).* @param Ox Output: Oxygen x coordinates.* @param Oy Output: Oxygen y coordinates.* @param Oz Output: Oxygen z coordinates.* @param H1x Output: First hydrogen x coordinates.* @param H1y Output: First hydrogen y coordinates.* @param H1z Output: First hydrogen z coordinates.* @param H2x Output: Second hydrogen x coordinates.* @param H2y Output: Second hydrogen y coordinates.* @param H2z Output: Second hydrogen z coordinates.*/static inline voidload_4_3atoms(float *address1, float *address2, float *address3, float *address4, vector float *Ox, vector float *Oy, vector float *Oz, vector float *H1x, vector float *H1y, vector float *H1z, vector float *H2x, vector float *H2y, vector float *H2z){ vector unsigned char perm; vector float tmp1,tmp2,tmp3; vector float c1a,c2a,c3a; vector float c1b,c2b,c3b; vector float c1c,c2c,c3c; vector float c1d,c2d,c3d; /* load the coordinates */ perm = vec_lvsl( 0, address1 ); tmp1 = vec_ld( 0, address1 ); tmp2 = vec_ld( 16, address1 ); tmp3 = vec_ld( 32, address1 ); c1a = vec_perm(tmp1,tmp2,perm); /* Oxa Oya Oza H1xa */ c2a = vec_perm(tmp2,tmp3,perm); /* H1ya H1za H2xa H2ya */ c3a = vec_perm(tmp3,tmp3,perm); /* H2za - - - */ perm = vec_lvsl( 0, address2 ); tmp1 = vec_ld( 0, address2 ); tmp2 = vec_ld( 16, address2 ); tmp3 = vec_ld( 32, address2 ); c1b = vec_perm(tmp1,tmp2,perm); /* Oxb Oyb Ozb H1xb */ c2b = vec_perm(tmp2,tmp3,perm); /* H1yb H1zb H2xb H2yb */ c3b = vec_perm(tmp3,tmp3,perm); /* H2zb - - - */ perm = vec_lvsl( 0, address3 ); tmp1 = vec_ld( 0, address3 ); tmp2 = vec_ld( 16, address3 ); tmp3 = vec_ld( 32, address3 ); c1c = vec_perm(tmp1,tmp2,perm); /* Oxc Oyc Ozc H1xc */ c2c = vec_perm(tmp2,tmp3,perm); /* H1yc H1zc H2xc H2yc */ c3c = vec_perm(tmp3,tmp3,perm); /* H2zc - - - */ perm = vec_lvsl( 0, address4 ); tmp1 = vec_ld( 0, address4 ); tmp2 = vec_ld( 16, address4 ); tmp3 = vec_ld( 32, address4 ); c1d = vec_perm(tmp1,tmp2,perm); /* Oxd Oyd Ozd H1xd */ c2d = vec_perm(tmp2,tmp3,perm); /* H1yd H1zd H2xd H2yd */ c3d = vec_perm(tmp3,tmp3,perm); /* H2zd - - - */ /* permute things */ tmp1 = vec_mergeh(c1a,c1c); /* Oxa Oxc Oya Oyc */ c1a = vec_mergel(c1a,c1c); /* Oza Ozc H1xa H1xc */ c1c = vec_mergeh(c1b,c1d); /* Oxb Oxd Oyb Oyd */ c1b = vec_mergel(c1b,c1d); /* Ozb Ozd H1xb H1xd */ c1d = vec_mergeh(c2a,c2c); /* H1ya H1yc H1za H1zc */ c2a = vec_mergel(c2a,c2c); /* H2xa H2xc H2ya H2yc */ c2c = vec_mergeh(c2b,c2d); /* H1yb H1yd H1zb H1zd */ c2b = vec_mergel(c2b,c2d); /* H2xb H2xd H2yb H2yd */ c3a = vec_mergeh(c3a,c3c); /* H2za H2zc - - */ c3b = vec_mergeh(c3b,c3d); /* H2zb H2zd - - */ *Ox = vec_mergeh(tmp1,c1c); /* Oxa Oxb Oxc Oxd */ *Oy = vec_mergel(tmp1,c1c); /* Oya Oyb Oyc Oyd */ *Oz = vec_mergeh(c1a,c1b); /* Oza Ozb Ozc Ozd */ *H1x = vec_mergel(c1a,c1b); /* H1xa H1xb H1xc H1xd */ *H1y = vec_mergeh(c1d,c2c); /* H1ya H1yb H1yc H1yd */ *H1z = vec_mergel(c1d,c2c); /* H1za H1zb H1zc H1zd */ *H2x = vec_mergeh(c2a,c2b); /* H2xa H2xb H2xc H2xd */ *H2y = vec_mergel(c2a,c2b); /* H2ya H2yb H2yc H2yd */ *H2z = vec_mergeh(c3a,c3b); /* H2za H2zb H2zc H2zd */}/** Load coords of 4 4-atom waters (4*12 floats) to SIMD vectors.** We use our knowledge about water to improve the loading performance.* The allocated memory is always 8-byte aligned, so with 12 atoms* we can always read 4 16-byte chunks (rounded down by vec_ld)* without going outside the current page (which might incur a page fault). * The extra elements before and after the water dont matter as long as we dont* try to write to them.** @param address1 Address of first coord in first water (oxygen x).* @param address2 Address of first coord in second water (oxygen x).* @param address3 Address of first coord in third water (oxygen x).* @param address4 Address of first coord in fourth water (oxygen x).* @param Ox Output: Oxygen x coordinates.* @param Oy Output: Oxygen y coordinates.* @param Oz Output: Oxygen z coordinates.* @param H1x Output: First hydrogen x coordinates.* @param H1y Output: First hydrogen y coordinates.* @param H1z Output: First hydrogen z coordinates.* @param H2x Output: Second hydrogen x coordinates.* @param H2y Output: Second hydrogen y coordinates.* @param H2z Output: Second hydrogen z coordinates.* @param Mx Output: Virtual site x coordinates.* @param My Output: Virtual site y coordinates.* @param Mz Output: Virtual site z coordinates.*/static inline void load_4_4atoms(float *address1, float *address2, float *address3, float *address4, vector float *Ox, vector float *Oy, vector float *Oz, vector float *H1x, vector float *H1y, vector float *H1z, vector float *H2x, vector float *H2y, vector float *H2z, vector float *Mx, vector float *My, vector float *Mz){ vector unsigned char perm; vector float tmp1,tmp2,tmp4; vector float c1a,c2a,c3a; vector float c1b,c2b,c3b; vector float c1c,c2c,c3c; vector float c1d,c2d,c3d; /* load the coordinates */ c1a = vec_ld( 0, address1 ); c2a = vec_ld( 16, address1 ); c3a = vec_ld( 32, address1 ); if(((unsigned int)address1) & 0xf) { /* Load extra data and rotate if not aligned */ tmp4 = vec_ld( 48, address1 ); perm = vec_lvsl( 0, address1 ); c1a = vec_perm(c1a,c2a,perm); /* Oxa Oya Oza H1xa */ c2a = vec_perm(c2a,c3a,perm); /* H1ya H1za H2xa H2ya */ c3a = vec_perm(c3a,tmp4,perm); /* H2za Mxa Mya Mza */ } c1b = vec_ld( 0, address2 ); c2b = vec_ld( 16, address2 ); c3b = vec_ld( 32, address2 ); if(((unsigned int)address2) & 0xf) { /* Load extra data and rotate if not aligned */ tmp4 = vec_ld( 48, address2 ); perm = vec_lvsl( 0, address2 ); c1b = vec_perm(c1b,c2b,perm); /* Oxb Oyb Ozb H1xb */ c2b = vec_perm(c2b,c3b,perm); /* H1yb H1zb H2xb H2yb */ c3b = vec_perm(c3b,tmp4,perm); /* H2zb Mxb Myb Mzb */ } c1c = vec_ld( 0, address3 );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?