SIMDCalc.cs 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291
  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. for (int j = 0; j < onecount; j++)
  305. {
  306. temp += t[j];
  307. }
  308. }
  309. if (c1 > 0)
  310. {
  311. for (int i = 0; i < c1; i++)
  312. {
  313. temp += (ptr[start + i] * ptr[start + i]);
  314. }
  315. }
  316. return MathF.Sqrt(temp / count);
  317. }
  318. public unsafe double Rms(ref double value, uint count)
  319. {
  320. if (count == 0) return 0;
  321. if (count == 1) return value;
  322. double temp = 0;
  323. double* ptr = (double*)Unsafe.AsPointer(ref value);
  324. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  325. uint c = count / onecount;
  326. uint c1 = count % onecount;
  327. uint start = c * onecount;
  328. ref var refvalue = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref value);
  329. for (int i = 0; i < c; i++)
  330. {
  331. ref var tempref = ref Unsafe.Add(ref refvalue, i);
  332. tempref *= tempref;
  333. for (int j = 0; j < onecount; j++)
  334. {
  335. temp += tempref[j];
  336. }
  337. }
  338. if (c1 > 0)
  339. {
  340. for (int i = 0; i < c1; i++)
  341. {
  342. temp += (ptr[start + i] * ptr[start + i]);
  343. }
  344. }
  345. return Math.Sqrt(temp / count);
  346. }
  347. public unsafe float Sum(ref float value, uint count)
  348. {
  349. if (count == 0) return 0;
  350. if (count == 1) return value;
  351. float* ptr = (float*)Unsafe.AsPointer(ref value);
  352. float temp = value;
  353. for (int i = 1; i < count; i++)
  354. {
  355. temp += ptr[i];
  356. }
  357. return temp;
  358. }
  359. public unsafe double Sum(ref double value, uint count)
  360. {
  361. if (count == 0) return 0;
  362. if (count == 1) return value;
  363. double* ptr = (double*)Unsafe.AsPointer(ref value);
  364. double temp = value;
  365. for (int i = 1; i < count; i++)
  366. {
  367. temp += ptr[i];
  368. }
  369. return temp;
  370. }
  371. }
  372. public sealed class SIMDFFT : IFFT
  373. {
  374. public SIMDFFT()
  375. {
  376. FFTW.NET.FftwInterop.Initialize();
  377. }
  378. public void FFT(double[] real, double[] imaginary)
  379. {
  380. var result = FFTW.NET.DFT.FFT(real, imaginary);
  381. var tempreal = result.Select(x => x.Real).ToArray();
  382. var tempimg = result.Select(x => x.Imaginary).ToArray();
  383. Unsafe.CopyBlock(ref Unsafe.As<double, byte>(ref real[0]), ref Unsafe.As<double, byte>(ref tempreal[0]), (uint)(real.Length * Unsafe.SizeOf<double>()));
  384. Unsafe.CopyBlock(ref Unsafe.As<double, byte>(ref imaginary[0]), ref Unsafe.As<double, byte>(ref tempimg[0]), (uint)(real.Length * Unsafe.SizeOf<double>()));
  385. }
  386. public void FFT(float[] real, float[] imaginary)
  387. {
  388. var result = FFTW.NET.DFT.FFT(real.Select(x=> (double)x).ToArray(), imaginary.Select(x=> (double)x).ToArray());
  389. var tempreal = result.Select(x => (float)x.Real).ToArray();
  390. var tempimg = result.Select(x => (float)x.Imaginary).ToArray();
  391. Unsafe.CopyBlock(ref Unsafe.As<float, byte>(ref real[0]), ref Unsafe.As<float, byte>(ref tempreal[0]), (uint)(real.Length * Unsafe.SizeOf<float>()));
  392. Unsafe.CopyBlock(ref Unsafe.As<float, byte>(ref imaginary[0]), ref Unsafe.As<float, byte>(ref tempimg[0]), (uint)(real.Length * Unsafe.SizeOf<float>()));
  393. }
  394. public void IFFT(double[] real, double[] imaginary)
  395. {
  396. var result = FFTW.NET.DFT.IFFT(real, imaginary);
  397. var tempreal = result.Select(x => x.Real).ToArray();
  398. var tempimg = result.Select(x => x.Imaginary).ToArray();
  399. Unsafe.CopyBlock(ref Unsafe.As<double, byte>(ref real[0]), ref Unsafe.As<double, byte>(ref tempreal[0]), (uint)(real.Length * Unsafe.SizeOf<double>()));
  400. Unsafe.CopyBlock(ref Unsafe.As<double, byte>(ref imaginary[0]), ref Unsafe.As<double, byte>(ref tempimg[0]), (uint)(real.Length * Unsafe.SizeOf<double>()));
  401. }
  402. public void IFFT(float[] real, float[] imaginary)
  403. {
  404. var result = FFTW.NET.DFT.IFFT(real.Select(x => (double)x).ToArray(), imaginary.Select(x => (double)x).ToArray());
  405. var tempreal = result.Select(x => (float)x.Real).ToArray();
  406. var tempimg = result.Select(x => (float)x.Imaginary).ToArray();
  407. Unsafe.CopyBlock(ref Unsafe.As<float, byte>(ref real[0]), ref Unsafe.As<float, byte>(ref tempreal[0]), (uint)(real.Length * Unsafe.SizeOf<float>()));
  408. Unsafe.CopyBlock(ref Unsafe.As<float, byte>(ref imaginary[0]), ref Unsafe.As<float, byte>(ref tempimg[0]), (uint)(real.Length * Unsafe.SizeOf<float>()));
  409. }
  410. }
  411. public unsafe sealed class SIMDAdd : IAdd
  412. {
  413. public void Add(ref float left, float right, uint count, ref float result)
  414. {
  415. if (count == 0) return;
  416. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  417. ref var desc = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref result);
  418. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  419. uint c = count / onecount;
  420. uint c1 = count % onecount;
  421. uint start = c * onecount;
  422. var rightarray = Enumerable.Repeat(right, (int)onecount).ToArray();
  423. ref var tempright = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref rightarray[0]);
  424. for (int i = 0; i < c; i++)
  425. {
  426. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  427. tempdesc = Unsafe.Add(ref source, i) + tempright;
  428. }
  429. if (c1 > 0)
  430. {
  431. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  432. float* resultptr = (float*)Unsafe.AsPointer(ref result);
  433. for (int i = 0; i < c1; i++)
  434. {
  435. resultptr[start + i] = leftptr[start + i] + right;
  436. }
  437. }
  438. }
  439. public void Add(ref float left, ref float right, uint count, ref float result)
  440. {
  441. if (count == 0) return;
  442. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  443. ref var desc = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref result);
  444. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  445. uint c = count / onecount;
  446. uint c1 = count % onecount;
  447. uint start = c * onecount;
  448. ref var tempright = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref right);
  449. for (int i = 0; i < c; i++)
  450. {
  451. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  452. tempdesc = Unsafe.Add(ref source, i) + Unsafe.Add(ref tempright, i);
  453. }
  454. if (c1 > 0)
  455. {
  456. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  457. float* resultptr = (float*)Unsafe.AsPointer(ref result);
  458. float* rightptr = (float*)Unsafe.AsPointer(ref right);
  459. for (int i = 0; i < c1; i++)
  460. {
  461. resultptr[start + i] = leftptr[start + i] + rightptr[start + i];
  462. }
  463. }
  464. }
  465. public void Add(ref float left, float right, uint count)
  466. {
  467. if (count == 0) return;
  468. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  469. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  470. uint c = count / onecount;
  471. uint c1 = count % onecount;
  472. uint start = c * onecount;
  473. var rightarray = Enumerable.Repeat(right, (int)onecount).ToArray();
  474. ref var tempright = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref rightarray[0]);
  475. for (int i = 0; i < c; i++)
  476. {
  477. ref var tempdesc = ref Unsafe.Add(ref source, i);
  478. tempdesc += tempright;
  479. }
  480. if (c1 > 0)
  481. {
  482. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  483. for (int i = 0; i < c1; i++)
  484. {
  485. leftptr[start + i] += right;
  486. }
  487. }
  488. }
  489. public void Add(ref float left, ref float right, uint count)
  490. {
  491. if (count == 0) return;
  492. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  493. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  494. uint c = count / onecount;
  495. uint c1 = count % onecount;
  496. uint start = c * onecount;
  497. ref var tempright = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref right);
  498. for (int i = 0; i < c; i++)
  499. {
  500. ref var tempdesc = ref Unsafe.Add(ref source, i);
  501. tempdesc += Unsafe.Add(ref tempright, i);
  502. }
  503. if (c1 > 0)
  504. {
  505. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  506. float* rightptr = (float*)Unsafe.AsPointer(ref right);
  507. for (int i = 0; i < c1; i++)
  508. {
  509. leftptr[start + i] += rightptr[start + i];
  510. }
  511. }
  512. }
  513. public void Add(ref double left, double right, uint count, ref double result)
  514. {
  515. if (count == 0) return;
  516. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  517. ref var desc = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref result);
  518. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  519. uint c = count / onecount;
  520. uint c1 = count % onecount;
  521. uint start = c * onecount;
  522. var rightarray = Enumerable.Repeat(right, (int)onecount).ToArray();
  523. ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref rightarray[0]);
  524. for (int i = 0; i < c; i++)
  525. {
  526. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  527. tempdesc = Unsafe.Add(ref source, i) + tempright;
  528. }
  529. if (c1 > 0)
  530. {
  531. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  532. double* resultptr = (double*)Unsafe.AsPointer(ref result);
  533. for (int i = 0; i < c1; i++)
  534. {
  535. resultptr[start + i] = leftptr[start + i] + right;
  536. }
  537. }
  538. }
  539. public void Add(ref double left, ref double right, uint count, ref double result)
  540. {
  541. if (count == 0) return;
  542. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  543. ref var desc = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref result);
  544. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  545. uint c = count / onecount;
  546. uint c1 = count % onecount;
  547. uint start = c * onecount;
  548. ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref right);
  549. for (int i = 0; i < c; i++)
  550. {
  551. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  552. tempdesc = Unsafe.Add(ref source, i) + Unsafe.Add(ref tempright, i);
  553. }
  554. if (c1 > 0)
  555. {
  556. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  557. double* resultptr = (double*)Unsafe.AsPointer(ref result);
  558. double* rightptr = (double*)Unsafe.AsPointer(ref right);
  559. for (int i = 0; i < c1; i++)
  560. {
  561. resultptr[start + i] = leftptr[start + i] + rightptr[start + i];
  562. }
  563. }
  564. }
  565. public void Add(ref double left, double right, uint count)
  566. {
  567. if (count == 0) return;
  568. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  569. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  570. uint c = count / onecount;
  571. uint c1 = count % onecount;
  572. uint start = c * onecount;
  573. var rightarray = Enumerable.Repeat(right, (int)onecount).ToArray();
  574. ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref rightarray[0]);
  575. for (int i = 0; i < c; i++)
  576. {
  577. ref var tempdesc = ref Unsafe.Add(ref source, i);
  578. tempdesc += tempright;
  579. }
  580. if (c1 > 0)
  581. {
  582. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  583. for (int i = 0; i < c1; i++)
  584. {
  585. leftptr[start + i] += right;
  586. }
  587. }
  588. }
  589. public void Add(ref double left, ref double right, uint count)
  590. {
  591. if (count == 0) return;
  592. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  593. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  594. uint c = count / onecount;
  595. uint c1 = count % onecount;
  596. uint start = c * onecount;
  597. ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref right);
  598. for (int i = 0; i < c; i++)
  599. {
  600. ref var tempdesc = ref Unsafe.Add(ref source, i);
  601. tempdesc += Unsafe.Add(ref tempright, i);
  602. }
  603. if (c1 > 0)
  604. {
  605. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  606. double* rightptr = (double*)Unsafe.AsPointer(ref right);
  607. for (int i = 0; i < c1; i++)
  608. {
  609. leftptr[start + i] += rightptr[start + i];
  610. }
  611. }
  612. }
  613. }
  614. public unsafe sealed class SIMDSubtract : ISubtract
  615. {
  616. public void Subtract(ref float left, float right, uint count, ref float result)
  617. {
  618. if (count == 0) return;
  619. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  620. ref var desc = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref result);
  621. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  622. uint c = count / onecount;
  623. uint c1 = count % onecount;
  624. uint start = c * onecount;
  625. var rightarray = Enumerable.Repeat(right, (int)onecount).ToArray();
  626. ref var tempright = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref rightarray[0]);
  627. for (int i = 0; i < c; i++)
  628. {
  629. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  630. tempdesc = Unsafe.Add(ref source, i) - tempright;
  631. }
  632. if (c1 > 0)
  633. {
  634. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  635. float* resultptr = (float*)Unsafe.AsPointer(ref result);
  636. for (int i = 0; i < c1; i++)
  637. {
  638. resultptr[start + i] = leftptr[start + i] - right;
  639. }
  640. }
  641. }
  642. public void Subtract(ref float left, ref float right, uint count, ref float result)
  643. {
  644. if (count == 0) return;
  645. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  646. ref var desc = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref result);
  647. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  648. uint c = count / onecount;
  649. uint c1 = count % onecount;
  650. uint start = c * onecount;
  651. ref var tempright = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref right);
  652. for (int i = 0; i < c; i++)
  653. {
  654. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  655. tempdesc = Unsafe.Add(ref source, i) - Unsafe.Add(ref tempright, i);
  656. }
  657. if (c1 > 0)
  658. {
  659. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  660. float* resultptr = (float*)Unsafe.AsPointer(ref result);
  661. float* rightptr = (float*)Unsafe.AsPointer(ref right);
  662. for (int i = 0; i < c1; i++)
  663. {
  664. resultptr[start + i] = leftptr[start + i] - rightptr[start + i];
  665. }
  666. }
  667. }
  668. public void Subtract(ref float left, float right, uint count)
  669. {
  670. if (count == 0) return;
  671. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  672. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  673. uint c = count / onecount;
  674. uint c1 = count % onecount;
  675. uint start = c * onecount;
  676. var rightarray = Enumerable.Repeat(right, (int)onecount).ToArray();
  677. ref var tempright = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref rightarray[0]);
  678. for (int i = 0; i < c; i++)
  679. {
  680. ref var tempdesc = ref Unsafe.Add(ref source, i);
  681. tempdesc -= tempright;
  682. }
  683. if (c1 > 0)
  684. {
  685. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  686. for (int i = 0; i < c1; i++)
  687. {
  688. leftptr[start + i] -= right;
  689. }
  690. }
  691. }
  692. public void Subtract(ref float left, ref float right, uint count)
  693. {
  694. if (count == 0) return;
  695. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  696. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  697. uint c = count / onecount;
  698. uint c1 = count % onecount;
  699. uint start = c * onecount;
  700. ref var tempright = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref right);
  701. for (int i = 0; i < c; i++)
  702. {
  703. ref var tempdesc = ref Unsafe.Add(ref source, i);
  704. tempdesc -= Unsafe.Add(ref tempright, i);
  705. }
  706. if (c1 > 0)
  707. {
  708. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  709. float* rightptr = (float*)Unsafe.AsPointer(ref right);
  710. for (int i = 0; i < c1; i++)
  711. {
  712. leftptr[start + i] -= rightptr[start + i];
  713. }
  714. }
  715. }
  716. public void Subtract(ref double left, double right, uint count, ref double result)
  717. {
  718. if (count == 0) return;
  719. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  720. ref var desc = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref result);
  721. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  722. uint c = count / onecount;
  723. uint c1 = count % onecount;
  724. uint start = c * onecount;
  725. var rightarray = Enumerable.Repeat(right, (int)onecount).ToArray();
  726. ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref rightarray[0]);
  727. for (int i = 0; i < c; i++)
  728. {
  729. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  730. tempdesc = Unsafe.Add(ref source, i) - tempright;
  731. }
  732. if (c1 > 0)
  733. {
  734. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  735. double* resultptr = (double*)Unsafe.AsPointer(ref result);
  736. for (int i = 0; i < c1; i++)
  737. {
  738. resultptr[start + i] = leftptr[start + i] - right;
  739. }
  740. }
  741. }
  742. public void Subtract(ref double left, ref double right, uint count, ref double result)
  743. {
  744. if (count == 0) return;
  745. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  746. ref var desc = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref result);
  747. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  748. uint c = count / onecount;
  749. uint c1 = count % onecount;
  750. uint start = c * onecount;
  751. ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref right);
  752. for (int i = 0; i < c; i++)
  753. {
  754. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  755. tempdesc = Unsafe.Add(ref source, i) - Unsafe.Add(ref tempright, i);
  756. }
  757. if (c1 > 0)
  758. {
  759. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  760. double* resultptr = (double*)Unsafe.AsPointer(ref result);
  761. double* rightptr = (double*)Unsafe.AsPointer(ref right);
  762. for (int i = 0; i < c1; i++)
  763. {
  764. resultptr[start + i] = leftptr[start + i] - rightptr[start + i];
  765. }
  766. }
  767. }
  768. public void Subtract(ref double left, double right, uint count)
  769. {
  770. if (count == 0) return;
  771. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  772. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  773. uint c = count / onecount;
  774. uint c1 = count % onecount;
  775. uint start = c * onecount;
  776. var rightarray = Enumerable.Repeat(right, (int)onecount).ToArray();
  777. ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref rightarray[0]);
  778. for (int i = 0; i < c; i++)
  779. {
  780. ref var tempdesc = ref Unsafe.Add(ref source, i);
  781. tempdesc -= tempright;
  782. }
  783. if (c1 > 0)
  784. {
  785. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  786. for (int i = 0; i < c1; i++)
  787. {
  788. leftptr[start + i] -= right;
  789. }
  790. }
  791. }
  792. public void Subtract(ref double left, ref double right, uint count)
  793. {
  794. if (count == 0) return;
  795. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  796. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  797. uint c = count / onecount;
  798. uint c1 = count % onecount;
  799. uint start = c * onecount;
  800. ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref right);
  801. for (int i = 0; i < c; i++)
  802. {
  803. ref var tempdesc = ref Unsafe.Add(ref source, i);
  804. tempdesc -= Unsafe.Add(ref tempright, i);
  805. }
  806. if (c1 > 0)
  807. {
  808. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  809. double* rightptr = (double*)Unsafe.AsPointer(ref right);
  810. for (int i = 0; i < c1; i++)
  811. {
  812. leftptr[start + i] -= rightptr[start + i];
  813. }
  814. }
  815. }
  816. }
  817. public unsafe sealed class SIMDMultiply : IMultiply
  818. {
  819. public void Multiply(ref float left, float right, uint count, ref float result)
  820. {
  821. if (count == 0) return;
  822. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  823. ref var desc = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref result);
  824. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  825. uint c = count / onecount;
  826. uint c1 = count % onecount;
  827. uint start = c * onecount;
  828. for (int i = 0; i < c; i++)
  829. {
  830. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  831. tempdesc = Unsafe.Add(ref source, i) * right;
  832. }
  833. if (c1 > 0)
  834. {
  835. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  836. float* resultptr = (float*)Unsafe.AsPointer(ref result);
  837. for (int i = 0; i < c1; i++)
  838. {
  839. resultptr[start + i] = leftptr[start + i] * right;
  840. }
  841. }
  842. }
  843. public void Multiply(ref float left, ref float right, uint count, ref float result)
  844. {
  845. if (count == 0) return;
  846. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  847. ref var desc = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref result);
  848. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  849. uint c = count / onecount;
  850. uint c1 = count % onecount;
  851. uint start = c * onecount;
  852. ref var tempright = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref right);
  853. for (int i = 0; i < c; i++)
  854. {
  855. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  856. tempdesc = Unsafe.Add(ref source, i) * Unsafe.Add(ref tempright, i);
  857. }
  858. if (c1 > 0)
  859. {
  860. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  861. float* resultptr = (float*)Unsafe.AsPointer(ref result);
  862. float* rightptr = (float*)Unsafe.AsPointer(ref right);
  863. for (int i = 0; i < c1; i++)
  864. {
  865. resultptr[start + i] = leftptr[start + i] * rightptr[start + i];
  866. }
  867. }
  868. }
  869. public void Multiply(ref float left, float right, uint count)
  870. {
  871. if (count == 0) return;
  872. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  873. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  874. uint c = count / onecount;
  875. uint c1 = count % onecount;
  876. uint start = c * onecount;
  877. for (int i = 0; i < c; i++)
  878. {
  879. ref var tempdesc = ref Unsafe.Add(ref source, i);
  880. tempdesc *= right;
  881. }
  882. if (c1 > 0)
  883. {
  884. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  885. for (int i = 0; i < c1; i++)
  886. {
  887. leftptr[start + i] *= right;
  888. }
  889. }
  890. }
  891. public void Multiply(ref float left, ref float right, uint count)
  892. {
  893. if (count == 0) return;
  894. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  895. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  896. uint c = count / onecount;
  897. uint c1 = count % onecount;
  898. uint start = c * onecount;
  899. ref var tempright = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref right);
  900. for (int i = 0; i < c; i++)
  901. {
  902. ref var tempdesc = ref Unsafe.Add(ref source, i);
  903. tempdesc *= Unsafe.Add(ref tempright, i);
  904. }
  905. if (c1 > 0)
  906. {
  907. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  908. float* rightptr = (float*)Unsafe.AsPointer(ref right);
  909. for (int i = 0; i < c1; i++)
  910. {
  911. leftptr[start + i] *= rightptr[start + i];
  912. }
  913. }
  914. }
  915. public void Multiply(ref double left, double right, uint count, ref double result)
  916. {
  917. if (count == 0) return;
  918. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  919. ref var desc = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref result);
  920. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  921. uint c = count / onecount;
  922. uint c1 = count % onecount;
  923. uint start = c * onecount;
  924. for (int i = 0; i < c; i++)
  925. {
  926. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  927. tempdesc = Unsafe.Add(ref source, i) * right;
  928. }
  929. if (c1 > 0)
  930. {
  931. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  932. double* resultptr = (double*)Unsafe.AsPointer(ref result);
  933. for (int i = 0; i < c1; i++)
  934. {
  935. resultptr[start + i] = leftptr[start + i] * right;
  936. }
  937. }
  938. }
  939. public void Multiply(ref double left, ref double right, uint count, ref double result)
  940. {
  941. if (count == 0) return;
  942. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  943. ref var desc = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref result);
  944. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  945. uint c = count / onecount;
  946. uint c1 = count % onecount;
  947. uint start = c * onecount;
  948. ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref right);
  949. for (int i = 0; i < c; i++)
  950. {
  951. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  952. tempdesc = Unsafe.Add(ref source, i) * Unsafe.Add(ref tempright, i);
  953. }
  954. if (c1 > 0)
  955. {
  956. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  957. double* resultptr = (double*)Unsafe.AsPointer(ref result);
  958. double* rightptr = (double*)Unsafe.AsPointer(ref right);
  959. for (int i = 0; i < c1; i++)
  960. {
  961. resultptr[start + i] = leftptr[start + i] * rightptr[start + i];
  962. }
  963. }
  964. }
  965. public void Multiply(ref double left, double right, uint count)
  966. {
  967. if (count == 0) return;
  968. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  969. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  970. uint c = count / onecount;
  971. uint c1 = count % onecount;
  972. uint start = c * onecount;
  973. for (int i = 0; i < c; i++)
  974. {
  975. ref var tempdesc = ref Unsafe.Add(ref source, i);
  976. tempdesc *= right;
  977. }
  978. if (c1 > 0)
  979. {
  980. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  981. for (int i = 0; i < c1; i++)
  982. {
  983. leftptr[start + i] *= right;
  984. }
  985. }
  986. }
  987. public void Multiply(ref double left, ref double right, uint count)
  988. {
  989. if (count == 0) return;
  990. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  991. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  992. uint c = count / onecount;
  993. uint c1 = count % onecount;
  994. uint start = c * onecount;
  995. ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref right);
  996. for (int i = 0; i < c; i++)
  997. {
  998. ref var tempdesc = ref Unsafe.Add(ref source, i);
  999. tempdesc *= Unsafe.Add(ref tempright, i);
  1000. }
  1001. if (c1 > 0)
  1002. {
  1003. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  1004. double* rightptr = (double*)Unsafe.AsPointer(ref right);
  1005. for (int i = 0; i < c1; i++)
  1006. {
  1007. leftptr[start + i] *= rightptr[start + i];
  1008. }
  1009. }
  1010. }
  1011. }
  1012. public unsafe sealed class SIMDDivision : IDivision
  1013. {
  1014. public void Division(ref float left, float right, uint count, ref float result)
  1015. {
  1016. if (count == 0) return;
  1017. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  1018. ref var desc = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref result);
  1019. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  1020. uint c = count / onecount;
  1021. uint c1 = count % onecount;
  1022. uint start = c * onecount;
  1023. for (int i = 0; i < c; i++)
  1024. {
  1025. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  1026. tempdesc = Unsafe.Add(ref source, i) / right;
  1027. }
  1028. if (c1 > 0)
  1029. {
  1030. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  1031. float* resultptr = (float*)Unsafe.AsPointer(ref result);
  1032. for (int i = 0; i < c1; i++)
  1033. {
  1034. resultptr[start + i] = leftptr[start + i] / right;
  1035. }
  1036. }
  1037. }
  1038. public void Division(ref float left, ref float right, uint count, ref float result)
  1039. {
  1040. if (count == 0) return;
  1041. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  1042. ref var desc = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref result);
  1043. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  1044. uint c = count / onecount;
  1045. uint c1 = count % onecount;
  1046. uint start = c * onecount;
  1047. ref var tempright = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref right);
  1048. for (int i = 0; i < c; i++)
  1049. {
  1050. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  1051. tempdesc = Unsafe.Add(ref source, i) / Unsafe.Add(ref tempright, i);
  1052. }
  1053. if (c1 > 0)
  1054. {
  1055. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  1056. float* resultptr = (float*)Unsafe.AsPointer(ref result);
  1057. float* rightptr = (float*)Unsafe.AsPointer(ref right);
  1058. for (int i = 0; i < c1; i++)
  1059. {
  1060. resultptr[start + i] = leftptr[start + i] / rightptr[start + i];
  1061. }
  1062. }
  1063. }
  1064. public void Division(ref float left, float right, uint count)
  1065. {
  1066. if (count == 0) return;
  1067. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  1068. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  1069. uint c = count / onecount;
  1070. uint c1 = count % onecount;
  1071. uint start = c * onecount;
  1072. for (int i = 0; i < c; i++)
  1073. {
  1074. ref var tempdesc = ref Unsafe.Add(ref source, i);
  1075. tempdesc /= right;
  1076. }
  1077. if (c1 > 0)
  1078. {
  1079. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  1080. for (int i = 0; i < c1; i++)
  1081. {
  1082. leftptr[start + i] /= right;
  1083. }
  1084. }
  1085. }
  1086. public void Division(ref float left, ref float right, uint count)
  1087. {
  1088. if (count == 0) return;
  1089. ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref left);
  1090. uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
  1091. uint c = count / onecount;
  1092. uint c1 = count % onecount;
  1093. uint start = c * onecount;
  1094. ref var tempright = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref right);
  1095. for (int i = 0; i < c; i++)
  1096. {
  1097. ref var tempdesc = ref Unsafe.Add(ref source, i);
  1098. tempdesc /= Unsafe.Add(ref tempright, i);
  1099. }
  1100. if (c1 > 0)
  1101. {
  1102. float* leftptr = (float*)Unsafe.AsPointer(ref left);
  1103. float* rightptr = (float*)Unsafe.AsPointer(ref right);
  1104. for (int i = 0; i < c1; i++)
  1105. {
  1106. leftptr[start + i] /= rightptr[start + i];
  1107. }
  1108. }
  1109. }
  1110. public void Division(ref double left, double right, uint count, ref double result)
  1111. {
  1112. if (count == 0) return;
  1113. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  1114. ref var desc = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref result);
  1115. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  1116. uint c = count / onecount;
  1117. uint c1 = count % onecount;
  1118. uint start = c * onecount;
  1119. for (int i = 0; i < c; i++)
  1120. {
  1121. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  1122. tempdesc = Unsafe.Add(ref source, i) / right;
  1123. }
  1124. if (c1 > 0)
  1125. {
  1126. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  1127. double* resultptr = (double*)Unsafe.AsPointer(ref result);
  1128. for (int i = 0; i < c1; i++)
  1129. {
  1130. resultptr[start + i] = leftptr[start + i] / right;
  1131. }
  1132. }
  1133. }
  1134. public void Division(ref double left, ref double right, uint count, ref double result)
  1135. {
  1136. if (count == 0) return;
  1137. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  1138. ref var desc = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref result);
  1139. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  1140. uint c = count / onecount;
  1141. uint c1 = count % onecount;
  1142. uint start = c * onecount;
  1143. ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref right);
  1144. for (int i = 0; i < c; i++)
  1145. {
  1146. ref var tempdesc = ref Unsafe.Add(ref desc, i);
  1147. tempdesc = Unsafe.Add(ref source, i) / Unsafe.Add(ref tempright, i);
  1148. }
  1149. if (c1 > 0)
  1150. {
  1151. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  1152. double* resultptr = (double*)Unsafe.AsPointer(ref result);
  1153. double* rightptr = (double*)Unsafe.AsPointer(ref right);
  1154. for (int i = 0; i < c1; i++)
  1155. {
  1156. resultptr[start + i] = leftptr[start + i] / rightptr[start + i];
  1157. }
  1158. }
  1159. }
  1160. public void Division(ref double left, double right, uint count)
  1161. {
  1162. if (count == 0) return;
  1163. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  1164. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  1165. uint c = count / onecount;
  1166. uint c1 = count % onecount;
  1167. uint start = c * onecount;
  1168. for (int i = 0; i < c; i++)
  1169. {
  1170. ref var tempdesc = ref Unsafe.Add(ref source, i);
  1171. tempdesc /= right;
  1172. }
  1173. if (c1 > 0)
  1174. {
  1175. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  1176. for (int i = 0; i < c1; i++)
  1177. {
  1178. leftptr[start + i] /= right;
  1179. }
  1180. }
  1181. }
  1182. public void Division(ref double left, ref double right, uint count)
  1183. {
  1184. if (count == 0) return;
  1185. ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
  1186. uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
  1187. uint c = count / onecount;
  1188. uint c1 = count % onecount;
  1189. uint start = c * onecount;
  1190. ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref right);
  1191. for (int i = 0; i < c; i++)
  1192. {
  1193. ref var tempdesc = ref Unsafe.Add(ref source, i);
  1194. tempdesc /= Unsafe.Add(ref tempright, i);
  1195. }
  1196. if (c1 > 0)
  1197. {
  1198. double* leftptr = (double*)Unsafe.AsPointer(ref left);
  1199. double* rightptr = (double*)Unsafe.AsPointer(ref right);
  1200. for (int i = 0; i < c1; i++)
  1201. {
  1202. leftptr[start + i] /= rightptr[start + i];
  1203. }
  1204. }
  1205. }
  1206. }
  1207. }