Advertisement
Guest User

Untitled

a guest
May 4th, 2023
158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.39 KB | None | 0 0
  1. #include <stdio.h>
  2. typedef unsigned long u64;
  3. void mul(u64 f[8], const u64 a[4], const u64 b[4]) {
  4. // a0..a3 b0..b3 f0..f7 mu t0..t1 s0..s3s0..s3
  5. u64 t0, t1, t2, mu;
  6. asm volatile (
  7. "movq %[a0], %[mu];"
  8. "mulxq %[b0], %[f4], %[t0]; movq %[f4], %[f0];"
  9. "mulxq %[b1], %[f5], %[t1]; addq %[t0], %[f5];"
  10. "mulxq %[b2], %[f6], %[t2]; adcq %[t1], %[f6];"
  11. "mulxq %[b3], %[f7], %[f4]; adcq %[t2], %[f7]; adcq $0, %[f4];"
  12. "movq %[a1], %[mu];"
  13. "mulxq %[b0], %[t2], %[t0]; addq %[t2], %[f5]; movq %[f5], %[f1];"
  14. "mulxq %[b1], %[t2], %[t1]; adcq %[t2], %[f6];"
  15. "mulxq %[b2], %[f5], %[t2]; adcq %[f5], %[f7];"
  16. "mulxq %[b3], %[mu], %[f5]; adcq %[mu], %[f4]; adcq $0, %[f5];"
  17. "addq %[t0], %[f6]; adcq %[t1], %[f7]; adcq %[t2], %[f4]; adcq $0, %[f5];"
  18. "movq %[a2], %[mu];"
  19. "mulxq %[b0], %[t2], %[t0]; addq %[t2], %[f6]; movq %[f6], %[f2];"
  20. "mulxq %[b1], %[t2], %[t1]; adcq %[t2], %[f7];"
  21. "mulxq %[b2], %[f6], %[t2]; adcq %[f6], %[f4];"
  22. "mulxq %[b3], %[mu], %[f6]; adcq %[mu], %[f5]; adcq $0, %[f6];"
  23. "addq %[t0], %[f7]; adcq %[t1], %[f4]; adcq %[t2], %[f5]; adcq $0, %[f6];"
  24. "movq %[a3], %[mu];"
  25. "mulxq %[b0], %[t2], %[t0]; addq %[t2], %[f7]; movq %[f7], %[f3];"
  26. "mulxq %[b1], %[t2], %[t1]; adcq %[t2], %[f4];"
  27. "mulxq %[b2], %[f7], %[t2]; adcq %[f7], %[f5];"
  28. "mulxq %[b3], %[mu], %[f7]; adcq %[mu], %[f6]; adcq $0, %[f7];"
  29. "addq %[t0], %[f4]; adcq %[t1], %[f5]; adcq %[t2], %[f6]; adcq $0, %[f7];"
  30. :
  31. [f0]"=&m"(f[0]), [f1]"=&m"(f[1]), [f2]"=&m"(f[2]), [f3]"=&m"(f[3]),
  32. [f4]"=&r"(f[4]), [f5]"=&r"(f[5]), [f6]"=&r"(f[6]), [f7]"=&r"(f[7]),
  33. [t0]"=&r"(t0),   [t1]"=&r"(t1),   [t2]"=&r"(t2),   [mu]"=&d"(mu):
  34. [a0]"m"(a[0]),   [a1]"m"(a[1]),   [a2]"m"(a[2]),   [a3]"m"(a[3]),
  35. [b0]"m"(b[0]),   [b1]"m"(b[1]),   [b2]"m"(b[2]),   [b3]"m"(b[3])
  36. );
  37. }
  38.  
  39.  
  40. void mulX(u64 f[8], const u64 a[4], const u64 b[4]) {
  41. // a0..a3 b0..b3 f0..f7 mu t0..t1 s0..s3s0..s3
  42. u64 t0, t1, mu, s0, s1, s2, s3;
  43. asm volatile (
  44. "movq %[a0], %[mu];"
  45. "mulxq %[b0], %[t0], %[s1]; movq %[t0], %[f0];"
  46. "mulxq %[b1], %[t0], %[s2]; addq %[t0], %[s1];"
  47. "mulxq %[b2], %[t0], %[s3]; adcq %[t0], %[s2];"
  48. "mulxq %[b3], %[t0], %[s0]; adcq %[t0], %[s3];  adcq $0, %[s0]; xorl %k[t1], %k[t1];"
  49. "movq %[a1], %[mu];"
  50. "mulxq %[b0], %[t0], %[t1]; adoxq %[t0], %[s1]; adcxq %[t1], %[s2]; movq %[s1], %[f1];"
  51. "mulxq %[b1], %[t0], %[t1]; adoxq %[t0], %[s2]; adcxq %[t1], %[s3];"
  52. "mulxq %[b2], %[t0], %[t1]; adoxq %[t0], %[s3]; adcxq %[t1], %[s0];"
  53. "mulxq %[b3], %[t0], %[t1]; adoxq %[t0], %[s0]; movl $0, %k[s1];"
  54.                                                "adoxq %[s1], %[s1]; adcxq %[t1], %[s1];"
  55. "movq %[a2], %[mu];"
  56. "mulxq %[b0], %[t0], %[t1]; adoxq %[t0], %[s2]; adcxq %[t1], %[s3]; movq %[s2], %[f2];"
  57. "mulxq %[b1], %[t0], %[t1]; adoxq %[t0], %[s3]; adcxq %[t1], %[s0];"
  58. "mulxq %[b2], %[t0], %[t1]; adoxq %[t0], %[s0]; adcxq %[t1], %[s1];"
  59. "mulxq %[b3], %[t0], %[t1]; adoxq %[t0], %[s1]; movl $0, %k[s2];"
  60.                                                "adoxq %[s2], %[s2]; adcxq %[t1], %[s2];"
  61. "movq %[a3], %[mu];"
  62. "mulxq %[b0], %[t0], %[t1]; adoxq %[t0], %[s3]; adcxq %[t1], %[s0]; movq %[s3], %[f3];"
  63. "mulxq %[b1], %[t0], %[t1]; adoxq %[t0], %[s0]; adcxq %[t1], %[s1]; movq %[s0], %[f4];"
  64. "mulxq %[b2], %[t0], %[t1]; adoxq %[t0], %[s1]; adcxq %[t1], %[s2]; movq %[s1], %[f5];"
  65. "mulxq %[b3], %[t0], %[t1]; adoxq %[t0], %[s2]; movl $0, %k[s3];    movq %[s2], %[f6];"
  66.                                                "adoxq %[s3], %[s3]; adcxq %[t1], %[s3];"
  67.                                                                    "movq %[s3], %[f7];":
  68. [f0]"=&m"(f[0]), [f1]"=&m"(f[1]), [f2]"=&m"(f[2]), [f3]"=&m"(f[3]),
  69. [f4]"=&m"(f[4]), [f5]"=&m"(f[5]), [f6]"=&m"(f[6]), [f7]"=&m"(f[7]),
  70. [t0]"=&r"(t0),   [t1]"=&r"(t1),   [mu]"=&d"(mu),
  71. [s0]"=&r"(s0),   [s1]"=&r"(s1),   [s2]"=&r"(s2),   [s3]"=&r"(s3):
  72. [a0]"m"(a[0]),   [a1]"m"(a[1]),   [a2]"m"(a[2]),   [a3]"m"(a[3]),
  73. [b0]"m"(b[0]),   [b1]"m"(b[1]),   [b2]"m"(b[2]),   [b3]"m"(b[3])
  74. );
  75. }
  76.  
  77. int main() {
  78.     u64 a[4] = {1,2,3,4};
  79.     u64 b[4] = {5,4,3,2};
  80.     u64 c[8];
  81.     for (unsigned i=0; ++i; )mulCall(c, a, b);
  82. }
  83.  
  84. /*
  85. $ gcc -DmulCall=mul -O2 66.c && sudo perf stat ./a.out # X
  86.  
  87.  Performance counter stats for './a.out':
  88.  
  89.          27,690.80 msec task-clock                #    0.998 CPUs utilized          
  90.              3,247      context-switches          #  117.259 /sec                  
  91.                586      cpu-migrations            #   21.162 /sec                  
  92.                 45      page-faults               #    1.625 /sec                  
  93.    106,431,860,062      cycles                    #    3.844 GHz                      (83.31%)
  94.        428,297,182      stalled-cycles-frontend   #    0.40% frontend cycles idle     (83.34%)
  95.     74,221,128,251      stalled-cycles-backend    #   69.74% backend cycles idle      (83.33%)
  96.    301,156,490,496      instructions              #    2.83  insn per cycle        
  97.                                                   #    0.25  stalled cycles per insn  (83.34%)
  98.     12,946,750,221      branches                  #  467.547 M/sec                    (83.33%)
  99.          2,007,761      branch-misses             #    0.02% of all branches          (83.34%)
  100.  
  101.       27.738868676 seconds time elapsed
  102.  
  103.       27.680633000 seconds user
  104.        0.011993000 seconds sys
  105.  
  106.  
  107. $ gcc -DmulCall=mulX -O2 66.c && sudo perf stat ./a.out # X
  108.  
  109.  Performance counter stats for './a.out':
  110.  
  111.          28,449.67 msec task-clock                #    0.998 CPUs utilized          
  112.              3,481      context-switches          #  122.356 /sec                  
  113.                533      cpu-migrations            #   18.735 /sec                  
  114.                 47      page-faults               #    1.652 /sec                  
  115.    110,006,534,480      cycles                    #    3.867 GHz                      (83.34%)
  116.        565,459,105      stalled-cycles-frontend   #    0.51% frontend cycles idle     (83.31%)
  117.     73,662,756,220      stalled-cycles-backend    #   66.96% backend cycles idle      (83.33%)
  118.    309,508,804,581      instructions              #    2.81  insn per cycle        
  119.                                                   #    0.24  stalled cycles per insn  (83.34%)
  120.     12,955,065,685      branches                  #  455.368 M/sec                    (83.33%)
  121.          2,288,864      branch-misses             #    0.02% of all branches          (83.35%)
  122.  
  123.       28.498440635 seconds time elapsed
  124.  
  125.       28.398338000 seconds user
  126.        0.051945000 seconds sys
  127.  
  128. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement