performance issues with SIMD function

Bogdan contact at szabobogdan.com
Fri Nov 3 15:11:31 UTC 2023


Hi everyone,

I was playing around with the intel-intrinsics library, trying to 
improve the speed of a simple area function. I could not see any 
performance improvements from the non-SIMD implementation. The 
SIMD version is a little bit slower even with LDC2 and --o3. Can 
anyone help me to understand what I am missing?


```D


///
double areaMeters(const double[2][] coordinates) @safe pure {
   if (coordinates.length <= 2) {
     return 0;
   }

   ///
   double rad(const double a) pure @safe @nogc {
     return a * PI / 180;
   }

   double result = 0;
   enum radius = 6_378_137;

   foreach(i; 0 .. coordinates.length - 1) {
     auto p1 = coordinates[i];
     auto p2 = coordinates[i + 1];

     result += rad(p2[0] - p1[0]) * (2 + sin(rad(p1[1])) + 
sin(rad(p2[1])));
   }

   return result * radius * radius / 2;
}

double areaMetersSimd(const double[2][] coordinates) @safe pure {
   if (coordinates.length <= 2) {
     return 0;
   }

   __m128d pi_2 = cast(__m128d)[PI, PI];
   __m128d pattern180_2 = cast(__m128d)[180., 180.];

   double result = 0;
   enum radius = 6_378_137;

   foreach(i; 0 .. coordinates.length - 1) {
     auto p1 = _mm_div_pd(_mm_mul_pd(cast(__m128d) coordinates[i], 
pi_2), pattern180_2);
     auto p2 = _mm_div_pd(_mm_mul_pd(cast(__m128d) coordinates[i + 
1], pi_2), pattern180_2);
     auto diff = _mm_sub_sd(p1, p2);

     result += diff[0] * (2 + sin(p1[1]) + sin(p2[1]));
   }

   return result * radius * radius / 2;
}


```


CPU info:
```
cat /proc/cpuinfo
processor       : 0
vendor_id       : AuthenticAMD
cpu family      : 23
model           : 113
model name      : AMD Ryzen 7 3800X 8-Core Processor
stepping        : 0
microcode       : 0x8701030
cpu MHz         : 3741.289
cache size      : 512 KB
physical id     : 0
siblings        : 16
core id         : 0
cpu cores       : 8
apicid          : 0
initial apicid  : 0
fpu             : yes
fpu_exception   : yes
cpuid level     : 16
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep 
mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall 
nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl 
nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq 
monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes 
xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy 
abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce 
topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb 
cat_l3 cdp_l3 hw_pstate ssbd mba ibpb stibp vmmcall fsgsbase bmi1 
avx2 smep bmi2 cqm rdt_a rdseed adx smap clflushopt clwb sha_ni 
xsaveopt xsavec xgetbv1 cqm_llc cqm_occup_llc cqm_mbm_total 
cqm_mbm_local clzero irperf xsaveerptr rdpru wbnoinvd arat npt 
lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid 
decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif 
v_spec_ctrl umip rdpid overflow_recov succor smca sev sev_es
bugs            : sysret_ss_attrs spectre_v1 spectre_v2 
spec_store_bypass retbleed smt_rsb srso
bogomips        : 7784.95
TLB size        : 3072 4K pages
clflush size    : 64
cache_alignment : 64
address sizes   : 43 bits physical, 48 bits virtual
power management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]
```

Thanks!
Bogdan


More information about the Digitalmars-d-learn mailing list