SIMDCalc.cs 55 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309
  1. using FFTW.NET;
  2. using FxpConvert.Common;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Numerics;
  7. using System.Runtime.CompilerServices;
  8. using System.Runtime.Intrinsics;
  9. using System.Text;
  10. using System.Threading.Tasks;
  11. namespace SIMDFxpConvert
  12. {
  13. public sealed class SIMDCalc : ICalc
  14. {
  15. public IAdd Add { get; } = new SIMDAdd();
  16. public ISubtract Subtract { get; } = new SIMDSubtract();
  17. public IMultiply Multiply { get; } = new SIMDMultiply();
  18. public IDivision Division { get; } = new SIMDDivision();
  19. public IFFT FFT { get; } = new SIMDFFT();
  20. public IArraySum Sum { get; } = new SIMDArraySum();
  21. public IClamp Clamp { get; } = new SIMDClamp();
  22. public unsafe void Fill(ref float result, float value, uint count)
  23. {
  24. if (count == 0) return;
  25. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref result);
  26. var desc = Vector512<float>.One * value;
  27. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  28. uint c = count / onecount;
  29. uint c1 = count % onecount;
  30. uint start = c * onecount;
  31. for (int i = 0; i < c; i++)
  32. {
  33. ref var tempdesc = ref Unsafe.Add(ref source, i);
  34. tempdesc = desc;
  35. }
  36. if (c1 > 0)
  37. {
  38. float* resultptr = (float*)Unsafe.AsPointer(ref result);
  39. for (int i = 0; i < c1; i++)
  40. {
  41. resultptr[start + i] = value;
  42. }
  43. }
  44. }
  45. public unsafe void Fill(ref double result, double value, uint count)
  46. {
  47. if (count == 0) return;
  48. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref result);
  49. var desc = Vector512<double>.One * value;
  50. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  51. uint c = count / onecount;
  52. uint c1 = count % onecount;
  53. uint start = c * onecount;
  54. for (int i = 0; i < c; i++)
  55. {
  56. ref var tempdesc = ref Unsafe.Add(ref source, i);
  57. tempdesc = desc;
  58. }
  59. if (c1 > 0)
  60. {
  61. double* resultptr = (double*)Unsafe.AsPointer(ref result);
  62. for (int i = 0; i < c1; i++)
  63. {
  64. resultptr[start + i] = value;
  65. }
  66. }
  67. }
  68. }
  69. public sealed class SIMDClamp : IClamp
  70. {
  71. public unsafe void Clamp(ref float value, float min, float max, uint count)
  72. {
  73. if (count == 0) return;
  74. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref value);
  75. var minv = Vector512<float>.One * min;
  76. var maxv = Vector512<float>.One * max;
  77. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  78. uint c = count / onecount;
  79. uint c1 = count % onecount;
  80. uint start = c * onecount;
  81. for (int i = 0; i < c; i++)
  82. {
  83. ref var tempdesc = ref Unsafe.Add(ref source, i);
  84. tempdesc =Vector512.Min(Vector512.Max(tempdesc,minv),maxv);
  85. }
  86. if (c1 > 0)
  87. {
  88. float* resultptr = (float*)Unsafe.AsPointer(ref value);
  89. for (int i = 0; i < c1; i++)
  90. {
  91. resultptr[start + i] = Math.Clamp(resultptr[start + i], min, max);
  92. }
  93. }
  94. }
  95. public unsafe void Clamp(ref double value, double min, double max, uint count)
  96. {
  97. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref value);
  98. var minv = Vector512<double>.One * min;
  99. var maxv = Vector512<double>.One * max;
  100. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  101. uint c = count / onecount;
  102. uint c1 = count % onecount;
  103. uint start = c * onecount;
  104. for (int i = 0; i < c; i++)
  105. {
  106. ref var tempdesc = ref Unsafe.Add(ref source, i);
  107. tempdesc = Vector512.Min(Vector512.Max(tempdesc, minv), maxv);
  108. }
  109. if (c1 > 0)
  110. {
  111. double* resultptr = (double*)Unsafe.AsPointer(ref value);
  112. for (int i = 0; i < c1; i++)
  113. {
  114. resultptr[start + i] = Math.Clamp(resultptr[start + i], min, max);
  115. }
  116. }
  117. }
  118. public unsafe void Clamp(ref float value, ref float min, ref float max, uint count)
  119. {
  120. if (count == 0) return;
  121. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref value);
  122. var minv = Unsafe.As<float,Vector512<float>>(ref min);
  123. var maxv = Unsafe.As<float, Vector512<float>>(ref max);
  124. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  125. uint c = count / onecount;
  126. uint c1 = count % onecount;
  127. uint start = c * onecount;
  128. for (int i = 0; i < c; i++)
  129. {
  130. ref var tempdesc = ref Unsafe.Add(ref source, i);
  131. tempdesc = Vector512.Min(Vector512.Max(tempdesc, Unsafe.Add(ref minv, i)), Unsafe.Add(ref maxv, i));
  132. }
  133. if (c1 > 0)
  134. {
  135. float* resultptr = (float*)Unsafe.AsPointer(ref value);
  136. for (int i = 0; i < c1; i++)
  137. {
  138. resultptr[start + i] = Math.Clamp(resultptr[start + i], ((float*)Unsafe.AsPointer(ref min))[start + i], ((float*)Unsafe.AsPointer(ref max))[start + i]);
  139. }
  140. }
  141. }
  142. public unsafe void Clamp(ref double value, ref double min, ref double max, uint count)
  143. {
  144. if (count == 0) return;
  145. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref value);
  146. var minv = Unsafe.As<double, Vector512<double>>(ref min);
  147. var maxv = Unsafe.As<double, Vector512<double>>(ref max);
  148. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  149. uint c = count / onecount;
  150. uint c1 = count % onecount;
  151. uint start = c * onecount;
  152. for (int i = 0; i < c; i++)
  153. {
  154. ref var tempdesc = ref Unsafe.Add(ref source, i);
  155. tempdesc = Vector512.Min(Vector512.Max(tempdesc, Unsafe.Add(ref minv, i)), Unsafe.Add(ref maxv, i));
  156. }
  157. if (c1 > 0)
  158. {
  159. double* resultptr = (double*)Unsafe.AsPointer(ref value);
  160. for (int i = 0; i < c1; i++)
  161. {
  162. resultptr[start + i] = Math.Clamp(resultptr[start + i], ((double*)Unsafe.AsPointer(ref min))[start + i], ((double*)Unsafe.AsPointer(ref max))[start + i]);
  163. }
  164. }
  165. }
  166. public unsafe void In(ref float value, float min, float max, uint count, ref int result)
  167. {
  168. if (count == 0) return ;
  169. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref value);
  170. var minv = Vector512<float>.One * min;
  171. var maxv = Vector512<float>.One * max;
  172. ref var resultv = ref Unsafe.As<int, Vector512<int>>(ref result);
  173. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  174. uint c = count / onecount;
  175. uint c1 = count % onecount;
  176. uint start = c * onecount;
  177. for (int i = 0; i < c; i++)
  178. {
  179. ref var tempdesc = ref Unsafe.Add(ref source, i);
  180. var r1 = Vector512.LessThan(tempdesc, minv).AsInt32();
  181. var r2 = Vector512.GreaterThan(tempdesc, maxv).AsInt32();
  182. ref var tempresv = ref Unsafe.Add(ref resultv, i);
  183. tempresv = r1 | r2;
  184. }
  185. if (c1 > 0)
  186. {
  187. float* valueptr = (float*)Unsafe.AsPointer(ref value);
  188. int* resultptr = (int*)Unsafe.AsPointer(ref result);
  189. for (int i = 0; i < c1; i++)
  190. {
  191. resultptr[start + i] = valueptr[start + i] < min || valueptr[start + i] > max ? -1 : 0;
  192. }
  193. }
  194. }
  195. public unsafe void In(ref double value, double min, double max, uint count, ref long result)
  196. {
  197. if (count == 0) return;
  198. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref value);
  199. var minv = Vector512<double>.One * min;
  200. var maxv = Vector512<double>.One * max;
  201. ref var resultv = ref Unsafe.As<long, Vector512<long>>(ref result);
  202. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  203. uint c = count / onecount;
  204. uint c1 = count % onecount;
  205. uint start = c * onecount;
  206. for (int i = 0; i < c; i++)
  207. {
  208. ref var tempdesc = ref Unsafe.Add(ref source, i);
  209. var r1 = Vector512.LessThan(tempdesc, minv).AsInt64();
  210. var r2 = Vector512.GreaterThan(tempdesc, maxv).AsInt64();
  211. ref var tempresv = ref Unsafe.Add(ref resultv, i);
  212. tempresv = r1 | r2;
  213. }
  214. if (c1 > 0)
  215. {
  216. double* valueptr = (double*)Unsafe.AsPointer(ref value);
  217. long* resultptr = (long*)Unsafe.AsPointer(ref result);
  218. for (int i = 0; i < c1; i++)
  219. {
  220. resultptr[start + i] = valueptr[start + i] < min || valueptr[start + i] > max ? -1 : 0;
  221. }
  222. }
  223. }
  224. public unsafe void In(ref float value, ref float min, ref float max, uint count, ref int result)
  225. {
  226. if (count == 0) return;
  227. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref value);
  228. var minv = Unsafe.As<float, Vector512<float>>(ref min);
  229. var maxv = Unsafe.As<float, Vector512<float>>(ref max);
  230. ref var resultv = ref Unsafe.As<int, Vector512<int>>(ref result);
  231. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  232. uint c = count / onecount;
  233. uint c1 = count % onecount;
  234. uint start = c * onecount;
  235. for (int i = 0; i < c; i++)
  236. {
  237. ref var tempdesc = ref Unsafe.Add(ref source, i);
  238. var r1 = Vector512.LessThan(tempdesc, Unsafe.Add(ref minv, i)).AsInt32();
  239. var r2 = Vector512.GreaterThan(tempdesc, Unsafe.Add(ref maxv, i)).AsInt32();
  240. ref var tempresv = ref Unsafe.Add(ref resultv, i);
  241. tempresv = r1 | r2;
  242. }
  243. if (c1 > 0)
  244. {
  245. float* valueptr = (float*)Unsafe.AsPointer(ref value);
  246. float* mintr = (float*)Unsafe.AsPointer(ref min);
  247. float* maxptr = (float*)Unsafe.AsPointer(ref max);
  248. int* resultptr = (int*)Unsafe.AsPointer(ref result);
  249. for (int i = 0; i < c1; i++)
  250. {
  251. resultptr[start + i] = valueptr[start + i] < mintr[start + i] || valueptr[start + i] > maxptr[start + i] ? -1 : 0;
  252. }
  253. }
  254. }
  255. public unsafe void In(ref double value, ref double min, ref double max, uint count, ref long result)
  256. {
  257. if (count == 0) return;
  258. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref value);
  259. var minv = Unsafe.As<double, Vector512<double>>(ref min);
  260. var maxv = Unsafe.As<double, Vector512<double>>(ref max);
  261. ref var resultv = ref Unsafe.As<long, Vector512<long>>(ref result);
  262. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  263. uint c = count / onecount;
  264. uint c1 = count % onecount;
  265. uint start = c * onecount;
  266. for (int i = 0; i < c; i++)
  267. {
  268. ref var tempdesc = ref Unsafe.Add(ref source, i);
  269. var r1 = Vector512.LessThan(tempdesc, Unsafe.Add(ref minv, i)).AsInt64();
  270. var r2 = Vector512.GreaterThan(tempdesc, Unsafe.Add(ref maxv, i)).AsInt64();
  271. ref var tempresv = ref Unsafe.Add(ref resultv, i);
  272. tempresv = r1 | r2;
  273. }
  274. if (c1 > 0)
  275. {
  276. double* valueptr = (double*)Unsafe.AsPointer(ref value);
  277. double* mintr = (double*)Unsafe.AsPointer(ref min);
  278. double* maxptr = (double*)Unsafe.AsPointer(ref max);
  279. long* resultptr = (long*)Unsafe.AsPointer(ref result);
  280. for (int i = 0; i < c1; i++)
  281. {
  282. resultptr[start + i] = valueptr[start + i] < mintr[start + i] || valueptr[start + i] > maxptr[start + i] ? -1 : 0;
  283. }
  284. }
  285. }
  286. }
  287. public sealed class SIMDArraySum : IArraySum
  288. {
  289. public unsafe float Rms(ref float value, uint count)
  290. {
  291. if (count == 0) return 0;
  292. if (count == 1) return value;
  293. float temp = 0;
  294. float* ptr = (float*)Unsafe.AsPointer(ref value);
  295. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  296. uint c = count / onecount;
  297. uint c1 = count % onecount;
  298. uint start = c * onecount;
  299. ref var refvalue = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref value);
  300. for (int i = 0; i < c; i++)
  301. {
  302. ref var tempref = ref Unsafe.Add(ref refvalue, i);
  303. var t = tempref * tempref;
  304. temp += Vector512.Sum(tempref);
  305. }
  306. if (c1 > 0)
  307. {
  308. for (int i = 0; i < c1; i++)
  309. {
  310. temp += (ptr[start + i] * ptr[start + i]);
  311. }
  312. }
  313. return MathF.Sqrt(temp / count);
  314. }
  315. public unsafe double Rms(ref double value, uint count)
  316. {
  317. if (count == 0) return 0;
  318. if (count == 1) return value;
  319. double temp = 0;
  320. double* ptr = (double*)Unsafe.AsPointer(ref value);
  321. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  322. uint c = count / onecount;
  323. uint c1 = count % onecount;
  324. uint start = c * onecount;
  325. ref var refvalue = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref value);
  326. for (int i = 0; i < c; i++)
  327. {
  328. ref var tempref = ref Unsafe.Add(ref refvalue, i);
  329. tempref *= tempref;
  330. temp += Vector512.Sum(tempref);
  331. }
  332. if (c1 > 0)
  333. {
  334. for (int i = 0; i < c1; i++)
  335. {
  336. temp += (ptr[start + i] * ptr[start + i]);
  337. }
  338. }
  339. return Math.Sqrt(temp / count);
  340. }
  341. public unsafe float Sum(ref float value, uint count)
  342. {
  343. if (count == 0) return 0;
  344. if (count == 1) return value;
  345. float temp = 0;
  346. float* ptr = (float*)Unsafe.AsPointer(ref value);
  347. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  348. uint c = count / onecount;
  349. uint c1 = count % onecount;
  350. uint start = c * onecount;
  351. ref var refvalue = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref value);
  352. for (int i = 0; i < c; i++)
  353. {
  354. temp += Vector512.Sum(Unsafe.Add(ref refvalue, i));
  355. }
  356. if (c1 > 0)
  357. {
  358. for (int i = 0; i < c1; i++)
  359. {
  360. temp += (ptr[start + i] * ptr[start + i]);
  361. }
  362. }
  363. return temp;
  364. }
  365. public unsafe double Sum(ref double value, uint count)
  366. {
  367. if (count == 0) return 0;
  368. if (count == 1) return value;
  369. double temp = 0;
  370. double* ptr = (double*)Unsafe.AsPointer(ref value);
  371. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  372. uint c = count / onecount;
  373. uint c1 = count % onecount;
  374. uint start = c * onecount;
  375. ref var refvalue = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref value);
  376. for (int i = 0; i < c; i++)
  377. {
  378. temp += Vector512.Sum(Unsafe.Add(ref refvalue, i));
  379. }
  380. if (c1 > 0)
  381. {
  382. for (int i = 0; i < c1; i++)
  383. {
  384. temp += (ptr[start + i] * ptr[start + i]);
  385. }
  386. }
  387. return temp;
  388. }
  389. }
  390. public sealed class SIMDFFT : IFFT
  391. {
  392. public SIMDFFT()
  393. {
  394. FFTW.NET.FftwInterop.Initialize();
  395. }
  396. public void FFT(double[] real, double[] imaginary)
  397. {
  398. var result = FFTW.NET.DFT.FFT(real, imaginary);
  399. var tempreal = result.Select(x => x.Real).ToArray();
  400. var tempimg = result.Select(x => x.Imaginary).ToArray();
  401. Unsafe.CopyBlock(ref Unsafe.As<double, byte>(ref real[0]), ref Unsafe.As<double, byte>(ref tempreal[0]), (uint)(real.Length * Unsafe.SizeOf<double>()));
  402. Unsafe.CopyBlock(ref Unsafe.As<double, byte>(ref imaginary[0]), ref Unsafe.As<double, byte>(ref tempimg[0]), (uint)(real.Length * Unsafe.SizeOf<double>()));
  403. }
  404. public void FFT(float[] real, float[] imaginary)
  405. {
  406. var result = FFTW.NET.DFT.FFT(real.Select(x=> (double)x).ToArray(), imaginary.Select(x=> (double)x).ToArray());
  407. var tempreal = result.Select(x => (float)x.Real).ToArray();
  408. var tempimg = result.Select(x => (float)x.Imaginary).ToArray();
  409. Unsafe.CopyBlock(ref Unsafe.As<float, byte>(ref real[0]), ref Unsafe.As<float, byte>(ref tempreal[0]), (uint)(real.Length * Unsafe.SizeOf<float>()));
  410. Unsafe.CopyBlock(ref Unsafe.As<float, byte>(ref imaginary[0]), ref Unsafe.As<float, byte>(ref tempimg[0]), (uint)(real.Length * Unsafe.SizeOf<float>()));
  411. }
  412. public void IFFT(double[] real, double[] imaginary)
  413. {
  414. var result = FFTW.NET.DFT.IFFT(real, imaginary);
  415. var tempreal = result.Select(x => x.Real).ToArray();
  416. var tempimg = result.Select(x => x.Imaginary).ToArray();
  417. Unsafe.CopyBlock(ref Unsafe.As<double, byte>(ref real[0]), ref Unsafe.As<double, byte>(ref tempreal[0]), (uint)(real.Length * Unsafe.SizeOf<double>()));
  418. Unsafe.CopyBlock(ref Unsafe.As<double, byte>(ref imaginary[0]), ref Unsafe.As<double, byte>(ref tempimg[0]), (uint)(real.Length * Unsafe.SizeOf<double>()));
  419. }
  420. public void IFFT(float[] real, float[] imaginary)
  421. {
  422. var result = FFTW.NET.DFT.IFFT(real.Select(x => (double)x).ToArray(), imaginary.Select(x => (double)x).ToArray());
  423. var tempreal = result.Select(x => (float)x.Real).ToArray();
  424. var tempimg = result.Select(x => (float)x.Imaginary).ToArray();
  425. Unsafe.CopyBlock(ref Unsafe.As<float, byte>(ref real[0]), ref Unsafe.As<float, byte>(ref tempreal[0]), (uint)(real.Length * Unsafe.SizeOf<float>()));
  426. Unsafe.CopyBlock(ref Unsafe.As<float, byte>(ref imaginary[0]), ref Unsafe.As<float, byte>(ref tempimg[0]), (uint)(real.Length * Unsafe.SizeOf<float>()));
  427. }
  428. }
  429. public unsafe sealed class SIMDAdd : IAdd
  430. {
  431. public void Add(ref float left, float right, uint count, ref float result)
  432. {
  433. if (count == 0) return;
  434. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  435. ref var desc = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref result);
  436. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  437. uint c = count / onecount;
  438. uint c1 = count % onecount;
  439. uint start = c * onecount;
  440. var rightarray = Enumerable.Repeat(right, (int)onecount).ToArray();
  441. ref var tempright = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref rightarray[0]);
  442. for (int i = 0; i < c; i++)
  443. {
  444. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  445. tempdesc = Unsafe.Add(ref source, i) + tempright;
  446. }
  447. if (c1 > 0)
  448. {
  449. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  450. float* resultptr = (float*)Unsafe.AsPointer(ref result);
  451. for (int i = 0; i < c1; i++)
  452. {
  453. resultptr[start + i] = leftptr[start + i] + right;
  454. }
  455. }
  456. }
  457. public void Add(ref float left, ref float right, uint count, ref float result)
  458. {
  459. if (count == 0) return;
  460. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  461. ref var desc = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref result);
  462. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  463. uint c = count / onecount;
  464. uint c1 = count % onecount;
  465. uint start = c * onecount;
  466. ref var tempright = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref right);
  467. for (int i = 0; i < c; i++)
  468. {
  469. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  470. tempdesc = Unsafe.Add(ref source, i) + Unsafe.Add(ref tempright, i);
  471. }
  472. if (c1 > 0)
  473. {
  474. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  475. float* resultptr = (float*)Unsafe.AsPointer(ref result);
  476. float* rightptr = (float*)Unsafe.AsPointer(ref right);
  477. for (int i = 0; i < c1; i++)
  478. {
  479. resultptr[start + i] = leftptr[start + i] + rightptr[start + i];
  480. }
  481. }
  482. }
  483. public void Add(ref float left, float right, uint count)
  484. {
  485. if (count == 0) return;
  486. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  487. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  488. uint c = count / onecount;
  489. uint c1 = count % onecount;
  490. uint start = c * onecount;
  491. var rightarray = Enumerable.Repeat(right, (int)onecount).ToArray();
  492. ref var tempright = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref rightarray[0]);
  493. for (int i = 0; i < c; i++)
  494. {
  495. ref var tempdesc = ref Unsafe.Add(ref source, i);
  496. tempdesc += tempright;
  497. }
  498. if (c1 > 0)
  499. {
  500. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  501. for (int i = 0; i < c1; i++)
  502. {
  503. leftptr[start + i] += right;
  504. }
  505. }
  506. }
  507. public void Add(ref float left, ref float right, uint count)
  508. {
  509. if (count == 0) return;
  510. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  511. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  512. uint c = count / onecount;
  513. uint c1 = count % onecount;
  514. uint start = c * onecount;
  515. ref var tempright = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref right);
  516. for (int i = 0; i < c; i++)
  517. {
  518. ref var tempdesc = ref Unsafe.Add(ref source, i);
  519. tempdesc += Unsafe.Add(ref tempright, i);
  520. }
  521. if (c1 > 0)
  522. {
  523. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  524. float* rightptr = (float*)Unsafe.AsPointer(ref right);
  525. for (int i = 0; i < c1; i++)
  526. {
  527. leftptr[start + i] += rightptr[start + i];
  528. }
  529. }
  530. }
  531. public void Add(ref double left, double right, uint count, ref double result)
  532. {
  533. if (count == 0) return;
  534. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  535. ref var desc = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref result);
  536. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  537. uint c = count / onecount;
  538. uint c1 = count % onecount;
  539. uint start = c * onecount;
  540. var rightarray = Enumerable.Repeat(right, (int)onecount).ToArray();
  541. ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref rightarray[0]);
  542. for (int i = 0; i < c; i++)
  543. {
  544. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  545. tempdesc = Unsafe.Add(ref source, i) + tempright;
  546. }
  547. if (c1 > 0)
  548. {
  549. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  550. double* resultptr = (double*)Unsafe.AsPointer(ref result);
  551. for (int i = 0; i < c1; i++)
  552. {
  553. resultptr[start + i] = leftptr[start + i] + right;
  554. }
  555. }
  556. }
  557. public void Add(ref double left, ref double right, uint count, ref double result)
  558. {
  559. if (count == 0) return;
  560. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  561. ref var desc = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref result);
  562. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  563. uint c = count / onecount;
  564. uint c1 = count % onecount;
  565. uint start = c * onecount;
  566. ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref right);
  567. for (int i = 0; i < c; i++)
  568. {
  569. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  570. tempdesc = Unsafe.Add(ref source, i) + Unsafe.Add(ref tempright, i);
  571. }
  572. if (c1 > 0)
  573. {
  574. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  575. double* resultptr = (double*)Unsafe.AsPointer(ref result);
  576. double* rightptr = (double*)Unsafe.AsPointer(ref right);
  577. for (int i = 0; i < c1; i++)
  578. {
  579. resultptr[start + i] = leftptr[start + i] + rightptr[start + i];
  580. }
  581. }
  582. }
  583. public void Add(ref double left, double right, uint count)
  584. {
  585. if (count == 0) return;
  586. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  587. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  588. uint c = count / onecount;
  589. uint c1 = count % onecount;
  590. uint start = c * onecount;
  591. var rightarray = Enumerable.Repeat(right, (int)onecount).ToArray();
  592. ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref rightarray[0]);
  593. for (int i = 0; i < c; i++)
  594. {
  595. ref var tempdesc = ref Unsafe.Add(ref source, i);
  596. tempdesc += tempright;
  597. }
  598. if (c1 > 0)
  599. {
  600. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  601. for (int i = 0; i < c1; i++)
  602. {
  603. leftptr[start + i] += right;
  604. }
  605. }
  606. }
  607. public void Add(ref double left, ref double right, uint count)
  608. {
  609. if (count == 0) return;
  610. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  611. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  612. uint c = count / onecount;
  613. uint c1 = count % onecount;
  614. uint start = c * onecount;
  615. ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref right);
  616. for (int i = 0; i < c; i++)
  617. {
  618. ref var tempdesc = ref Unsafe.Add(ref source, i);
  619. tempdesc += Unsafe.Add(ref tempright, i);
  620. }
  621. if (c1 > 0)
  622. {
  623. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  624. double* rightptr = (double*)Unsafe.AsPointer(ref right);
  625. for (int i = 0; i < c1; i++)
  626. {
  627. leftptr[start + i] += rightptr[start + i];
  628. }
  629. }
  630. }
  631. }
  632. public unsafe sealed class SIMDSubtract : ISubtract
  633. {
  634. public void Subtract(ref float left, float right, uint count, ref float result)
  635. {
  636. if (count == 0) return;
  637. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  638. ref var desc = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref result);
  639. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  640. uint c = count / onecount;
  641. uint c1 = count % onecount;
  642. uint start = c * onecount;
  643. var rightarray = Enumerable.Repeat(right, (int)onecount).ToArray();
  644. ref var tempright = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref rightarray[0]);
  645. for (int i = 0; i < c; i++)
  646. {
  647. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  648. tempdesc = Unsafe.Add(ref source, i) - tempright;
  649. }
  650. if (c1 > 0)
  651. {
  652. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  653. float* resultptr = (float*)Unsafe.AsPointer(ref result);
  654. for (int i = 0; i < c1; i++)
  655. {
  656. resultptr[start + i] = leftptr[start + i] - right;
  657. }
  658. }
  659. }
  660. public void Subtract(ref float left, ref float right, uint count, ref float result)
  661. {
  662. if (count == 0) return;
  663. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  664. ref var desc = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref result);
  665. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  666. uint c = count / onecount;
  667. uint c1 = count % onecount;
  668. uint start = c * onecount;
  669. ref var tempright = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref right);
  670. for (int i = 0; i < c; i++)
  671. {
  672. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  673. tempdesc = Unsafe.Add(ref source, i) - Unsafe.Add(ref tempright, i);
  674. }
  675. if (c1 > 0)
  676. {
  677. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  678. float* resultptr = (float*)Unsafe.AsPointer(ref result);
  679. float* rightptr = (float*)Unsafe.AsPointer(ref right);
  680. for (int i = 0; i < c1; i++)
  681. {
  682. resultptr[start + i] = leftptr[start + i] - rightptr[start + i];
  683. }
  684. }
  685. }
  686. public void Subtract(ref float left, float right, uint count)
  687. {
  688. if (count == 0) return;
  689. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  690. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  691. uint c = count / onecount;
  692. uint c1 = count % onecount;
  693. uint start = c * onecount;
  694. var rightarray = Enumerable.Repeat(right, (int)onecount).ToArray();
  695. ref var tempright = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref rightarray[0]);
  696. for (int i = 0; i < c; i++)
  697. {
  698. ref var tempdesc = ref Unsafe.Add(ref source, i);
  699. tempdesc -= tempright;
  700. }
  701. if (c1 > 0)
  702. {
  703. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  704. for (int i = 0; i < c1; i++)
  705. {
  706. leftptr[start + i] -= right;
  707. }
  708. }
  709. }
  710. public void Subtract(ref float left, ref float right, uint count)
  711. {
  712. if (count == 0) return;
  713. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  714. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  715. uint c = count / onecount;
  716. uint c1 = count % onecount;
  717. uint start = c * onecount;
  718. ref var tempright = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref right);
  719. for (int i = 0; i < c; i++)
  720. {
  721. ref var tempdesc = ref Unsafe.Add(ref source, i);
  722. tempdesc -= Unsafe.Add(ref tempright, i);
  723. }
  724. if (c1 > 0)
  725. {
  726. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  727. float* rightptr = (float*)Unsafe.AsPointer(ref right);
  728. for (int i = 0; i < c1; i++)
  729. {
  730. leftptr[start + i] -= rightptr[start + i];
  731. }
  732. }
  733. }
  734. public void Subtract(ref double left, double right, uint count, ref double result)
  735. {
  736. if (count == 0) return;
  737. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  738. ref var desc = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref result);
  739. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  740. uint c = count / onecount;
  741. uint c1 = count % onecount;
  742. uint start = c * onecount;
  743. var rightarray = Enumerable.Repeat(right, (int)onecount).ToArray();
  744. ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref rightarray[0]);
  745. for (int i = 0; i < c; i++)
  746. {
  747. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  748. tempdesc = Unsafe.Add(ref source, i) - tempright;
  749. }
  750. if (c1 > 0)
  751. {
  752. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  753. double* resultptr = (double*)Unsafe.AsPointer(ref result);
  754. for (int i = 0; i < c1; i++)
  755. {
  756. resultptr[start + i] = leftptr[start + i] - right;
  757. }
  758. }
  759. }
  760. public void Subtract(ref double left, ref double right, uint count, ref double result)
  761. {
  762. if (count == 0) return;
  763. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  764. ref var desc = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref result);
  765. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  766. uint c = count / onecount;
  767. uint c1 = count % onecount;
  768. uint start = c * onecount;
  769. ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref right);
  770. for (int i = 0; i < c; i++)
  771. {
  772. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  773. tempdesc = Unsafe.Add(ref source, i) - Unsafe.Add(ref tempright, i);
  774. }
  775. if (c1 > 0)
  776. {
  777. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  778. double* resultptr = (double*)Unsafe.AsPointer(ref result);
  779. double* rightptr = (double*)Unsafe.AsPointer(ref right);
  780. for (int i = 0; i < c1; i++)
  781. {
  782. resultptr[start + i] = leftptr[start + i] - rightptr[start + i];
  783. }
  784. }
  785. }
  786. public void Subtract(ref double left, double right, uint count)
  787. {
  788. if (count == 0) return;
  789. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  790. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  791. uint c = count / onecount;
  792. uint c1 = count % onecount;
  793. uint start = c * onecount;
  794. var rightarray = Enumerable.Repeat(right, (int)onecount).ToArray();
  795. ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref rightarray[0]);
  796. for (int i = 0; i < c; i++)
  797. {
  798. ref var tempdesc = ref Unsafe.Add(ref source, i);
  799. tempdesc -= tempright;
  800. }
  801. if (c1 > 0)
  802. {
  803. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  804. for (int i = 0; i < c1; i++)
  805. {
  806. leftptr[start + i] -= right;
  807. }
  808. }
  809. }
  810. public void Subtract(ref double left, ref double right, uint count)
  811. {
  812. if (count == 0) return;
  813. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  814. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  815. uint c = count / onecount;
  816. uint c1 = count % onecount;
  817. uint start = c * onecount;
  818. ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref right);
  819. for (int i = 0; i < c; i++)
  820. {
  821. ref var tempdesc = ref Unsafe.Add(ref source, i);
  822. tempdesc -= Unsafe.Add(ref tempright, i);
  823. }
  824. if (c1 > 0)
  825. {
  826. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  827. double* rightptr = (double*)Unsafe.AsPointer(ref right);
  828. for (int i = 0; i < c1; i++)
  829. {
  830. leftptr[start + i] -= rightptr[start + i];
  831. }
  832. }
  833. }
  834. }
  835. public unsafe sealed class SIMDMultiply : IMultiply
  836. {
  837. public void Multiply(ref float left, float right, uint count, ref float result)
  838. {
  839. if (count == 0) return;
  840. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  841. ref var desc = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref result);
  842. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  843. uint c = count / onecount;
  844. uint c1 = count % onecount;
  845. uint start = c * onecount;
  846. for (int i = 0; i < c; i++)
  847. {
  848. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  849. tempdesc = Unsafe.Add(ref source, i) * right;
  850. }
  851. if (c1 > 0)
  852. {
  853. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  854. float* resultptr = (float*)Unsafe.AsPointer(ref result);
  855. for (int i = 0; i < c1; i++)
  856. {
  857. resultptr[start + i] = leftptr[start + i] * right;
  858. }
  859. }
  860. }
  861. public void Multiply(ref float left, ref float right, uint count, ref float result)
  862. {
  863. if (count == 0) return;
  864. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  865. ref var desc = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref result);
  866. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  867. uint c = count / onecount;
  868. uint c1 = count % onecount;
  869. uint start = c * onecount;
  870. ref var tempright = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref right);
  871. for (int i = 0; i < c; i++)
  872. {
  873. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  874. tempdesc = Unsafe.Add(ref source, i) * Unsafe.Add(ref tempright, i);
  875. }
  876. if (c1 > 0)
  877. {
  878. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  879. float* resultptr = (float*)Unsafe.AsPointer(ref result);
  880. float* rightptr = (float*)Unsafe.AsPointer(ref right);
  881. for (int i = 0; i < c1; i++)
  882. {
  883. resultptr[start + i] = leftptr[start + i] * rightptr[start + i];
  884. }
  885. }
  886. }
  887. public void Multiply(ref float left, float right, uint count)
  888. {
  889. if (count == 0) return;
  890. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  891. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  892. uint c = count / onecount;
  893. uint c1 = count % onecount;
  894. uint start = c * onecount;
  895. for (int i = 0; i < c; i++)
  896. {
  897. ref var tempdesc = ref Unsafe.Add(ref source, i);
  898. tempdesc *= right;
  899. }
  900. if (c1 > 0)
  901. {
  902. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  903. for (int i = 0; i < c1; i++)
  904. {
  905. leftptr[start + i] *= right;
  906. }
  907. }
  908. }
  909. public void Multiply(ref float left, ref float right, uint count)
  910. {
  911. if (count == 0) return;
  912. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  913. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  914. uint c = count / onecount;
  915. uint c1 = count % onecount;
  916. uint start = c * onecount;
  917. ref var tempright = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref right);
  918. for (int i = 0; i < c; i++)
  919. {
  920. ref var tempdesc = ref Unsafe.Add(ref source, i);
  921. tempdesc *= Unsafe.Add(ref tempright, i);
  922. }
  923. if (c1 > 0)
  924. {
  925. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  926. float* rightptr = (float*)Unsafe.AsPointer(ref right);
  927. for (int i = 0; i < c1; i++)
  928. {
  929. leftptr[start + i] *= rightptr[start + i];
  930. }
  931. }
  932. }
  933. public void Multiply(ref double left, double right, uint count, ref double result)
  934. {
  935. if (count == 0) return;
  936. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  937. ref var desc = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref result);
  938. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  939. uint c = count / onecount;
  940. uint c1 = count % onecount;
  941. uint start = c * onecount;
  942. for (int i = 0; i < c; i++)
  943. {
  944. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  945. tempdesc = Unsafe.Add(ref source, i) * right;
  946. }
  947. if (c1 > 0)
  948. {
  949. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  950. double* resultptr = (double*)Unsafe.AsPointer(ref result);
  951. for (int i = 0; i < c1; i++)
  952. {
  953. resultptr[start + i] = leftptr[start + i] * right;
  954. }
  955. }
  956. }
  957. public void Multiply(ref double left, ref double right, uint count, ref double result)
  958. {
  959. if (count == 0) return;
  960. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  961. ref var desc = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref result);
  962. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  963. uint c = count / onecount;
  964. uint c1 = count % onecount;
  965. uint start = c * onecount;
  966. ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref right);
  967. for (int i = 0; i < c; i++)
  968. {
  969. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  970. tempdesc = Unsafe.Add(ref source, i) * Unsafe.Add(ref tempright, i);
  971. }
  972. if (c1 > 0)
  973. {
  974. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  975. double* resultptr = (double*)Unsafe.AsPointer(ref result);
  976. double* rightptr = (double*)Unsafe.AsPointer(ref right);
  977. for (int i = 0; i < c1; i++)
  978. {
  979. resultptr[start + i] = leftptr[start + i] * rightptr[start + i];
  980. }
  981. }
  982. }
  983. public void Multiply(ref double left, double right, uint count)
  984. {
  985. if (count == 0) return;
  986. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  987. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  988. uint c = count / onecount;
  989. uint c1 = count % onecount;
  990. uint start = c * onecount;
  991. for (int i = 0; i < c; i++)
  992. {
  993. ref var tempdesc = ref Unsafe.Add(ref source, i);
  994. tempdesc *= right;
  995. }
  996. if (c1 > 0)
  997. {
  998. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  999. for (int i = 0; i < c1; i++)
  1000. {
  1001. leftptr[start + i] *= right;
  1002. }
  1003. }
  1004. }
  1005. public void Multiply(ref double left, ref double right, uint count)
  1006. {
  1007. if (count == 0) return;
  1008. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  1009. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  1010. uint c = count / onecount;
  1011. uint c1 = count % onecount;
  1012. uint start = c * onecount;
  1013. ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref right);
  1014. for (int i = 0; i < c; i++)
  1015. {
  1016. ref var tempdesc = ref Unsafe.Add(ref source, i);
  1017. tempdesc *= Unsafe.Add(ref tempright, i);
  1018. }
  1019. if (c1 > 0)
  1020. {
  1021. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  1022. double* rightptr = (double*)Unsafe.AsPointer(ref right);
  1023. for (int i = 0; i < c1; i++)
  1024. {
  1025. leftptr[start + i] *= rightptr[start + i];
  1026. }
  1027. }
  1028. }
  1029. }
  1030. public unsafe sealed class SIMDDivision : IDivision
  1031. {
  1032. public void Division(ref float left, float right, uint count, ref float result)
  1033. {
  1034. if (count == 0) return;
  1035. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  1036. ref var desc = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref result);
  1037. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  1038. uint c = count / onecount;
  1039. uint c1 = count % onecount;
  1040. uint start = c * onecount;
  1041. for (int i = 0; i < c; i++)
  1042. {
  1043. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  1044. tempdesc = Unsafe.Add(ref source, i) / right;
  1045. }
  1046. if (c1 > 0)
  1047. {
  1048. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  1049. float* resultptr = (float*)Unsafe.AsPointer(ref result);
  1050. for (int i = 0; i < c1; i++)
  1051. {
  1052. resultptr[start + i] = leftptr[start + i] / right;
  1053. }
  1054. }
  1055. }
  1056. public void Division(ref float left, ref float right, uint count, ref float result)
  1057. {
  1058. if (count == 0) return;
  1059. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  1060. ref var desc = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref result);
  1061. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  1062. uint c = count / onecount;
  1063. uint c1 = count % onecount;
  1064. uint start = c * onecount;
  1065. ref var tempright = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref right);
  1066. for (int i = 0; i < c; i++)
  1067. {
  1068. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  1069. tempdesc = Unsafe.Add(ref source, i) / Unsafe.Add(ref tempright, i);
  1070. }
  1071. if (c1 > 0)
  1072. {
  1073. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  1074. float* resultptr = (float*)Unsafe.AsPointer(ref result);
  1075. float* rightptr = (float*)Unsafe.AsPointer(ref right);
  1076. for (int i = 0; i < c1; i++)
  1077. {
  1078. resultptr[start + i] = leftptr[start + i] / rightptr[start + i];
  1079. }
  1080. }
  1081. }
  1082. public void Division(ref float left, float right, uint count)
  1083. {
  1084. if (count == 0) return;
  1085. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  1086. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  1087. uint c = count / onecount;
  1088. uint c1 = count % onecount;
  1089. uint start = c * onecount;
  1090. for (int i = 0; i < c; i++)
  1091. {
  1092. ref var tempdesc = ref Unsafe.Add(ref source, i);
  1093. tempdesc /= right;
  1094. }
  1095. if (c1 > 0)
  1096. {
  1097. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  1098. for (int i = 0; i < c1; i++)
  1099. {
  1100. leftptr[start + i] /= right;
  1101. }
  1102. }
  1103. }
  1104. public void Division(ref float left, ref float right, uint count)
  1105. {
  1106. if (count == 0) return;
  1107. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  1108. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  1109. uint c = count / onecount;
  1110. uint c1 = count % onecount;
  1111. uint start = c * onecount;
  1112. ref var tempright = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref right);
  1113. for (int i = 0; i < c; i++)
  1114. {
  1115. ref var tempdesc = ref Unsafe.Add(ref source, i);
  1116. tempdesc /= Unsafe.Add(ref tempright, i);
  1117. }
  1118. if (c1 > 0)
  1119. {
  1120. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  1121. float* rightptr = (float*)Unsafe.AsPointer(ref right);
  1122. for (int i = 0; i < c1; i++)
  1123. {
  1124. leftptr[start + i] /= rightptr[start + i];
  1125. }
  1126. }
  1127. }
  1128. public void Division(ref double left, double right, uint count, ref double result)
  1129. {
  1130. if (count == 0) return;
  1131. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  1132. ref var desc = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref result);
  1133. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  1134. uint c = count / onecount;
  1135. uint c1 = count % onecount;
  1136. uint start = c * onecount;
  1137. for (int i = 0; i < c; i++)
  1138. {
  1139. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  1140. tempdesc = Unsafe.Add(ref source, i) / right;
  1141. }
  1142. if (c1 > 0)
  1143. {
  1144. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  1145. double* resultptr = (double*)Unsafe.AsPointer(ref result);
  1146. for (int i = 0; i < c1; i++)
  1147. {
  1148. resultptr[start + i] = leftptr[start + i] / right;
  1149. }
  1150. }
  1151. }
  1152. public void Division(ref double left, ref double right, uint count, ref double result)
  1153. {
  1154. if (count == 0) return;
  1155. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  1156. ref var desc = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref result);
  1157. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  1158. uint c = count / onecount;
  1159. uint c1 = count % onecount;
  1160. uint start = c * onecount;
  1161. ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref right);
  1162. for (int i = 0; i < c; i++)
  1163. {
  1164. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  1165. tempdesc = Unsafe.Add(ref source, i) / Unsafe.Add(ref tempright, i);
  1166. }
  1167. if (c1 > 0)
  1168. {
  1169. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  1170. double* resultptr = (double*)Unsafe.AsPointer(ref result);
  1171. double* rightptr = (double*)Unsafe.AsPointer(ref right);
  1172. for (int i = 0; i < c1; i++)
  1173. {
  1174. resultptr[start + i] = leftptr[start + i] / rightptr[start + i];
  1175. }
  1176. }
  1177. }
  1178. public void Division(ref double left, double right, uint count)
  1179. {
  1180. if (count == 0) return;
  1181. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  1182. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  1183. uint c = count / onecount;
  1184. uint c1 = count % onecount;
  1185. uint start = c * onecount;
  1186. for (int i = 0; i < c; i++)
  1187. {
  1188. ref var tempdesc = ref Unsafe.Add(ref source, i);
  1189. tempdesc /= right;
  1190. }
  1191. if (c1 > 0)
  1192. {
  1193. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  1194. for (int i = 0; i < c1; i++)
  1195. {
  1196. leftptr[start + i] /= right;
  1197. }
  1198. }
  1199. }
  1200. public void Division(ref double left, ref double right, uint count)
  1201. {
  1202. if (count == 0) return;
  1203. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  1204. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  1205. uint c = count / onecount;
  1206. uint c1 = count % onecount;
  1207. uint start = c * onecount;
  1208. ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref right);
  1209. for (int i = 0; i < c; i++)
  1210. {
  1211. ref var tempdesc = ref Unsafe.Add(ref source, i);
  1212. tempdesc /= Unsafe.Add(ref tempright, i);
  1213. }
  1214. if (c1 > 0)
  1215. {
  1216. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  1217. double* rightptr = (double*)Unsafe.AsPointer(ref right);
  1218. for (int i = 0; i < c1; i++)
  1219. {
  1220. leftptr[start + i] /= rightptr[start + i];
  1221. }
  1222. }
  1223. }
  1224. }
  1225. }