Advertisement
Guest User

Untitled

a guest
Aug 18th, 2019
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.96 KB | None | 0 0
  1. static inline int mandel_scalar1(double cr, double ci, int count) {
  2. double zr = cr, zi = ci;
  3. int i, cmp;
  4.  
  5. for (i = 0; i < count; ++i) {
  6. double rr = zr*zr;
  7. double ii = zi*zi;
  8.  
  9. cmp = rr + ii <= 4.;
  10. if (!cmp) break;
  11.  
  12. double nzr = rr - ii;
  13. double nzi = 2. * zr * zi;
  14.  
  15. zr = nzr + cr;
  16. zi = nzi + ci;
  17. }
  18. return cmp;
  19. }
  20.  
  21. void mandelbrot_scalar1(double x0, double y0, double x1, double y1, int width, int height, int maxIter, unsigned char* output) {
  22. double dx = (x1 - x0) / width;
  23. double dy = (y1 - y0) / width;
  24.  
  25. #pragma omp parallel for default(none) firstprivate(x0, y0, dx, dy, width, height, maxIter) shared(output) schedule(guided)
  26. for (int j = 0; j < height; ++j) {
  27. unsigned char* row = output + j*(width/8);
  28. for (int I = 0; I < width/8; ++I) {
  29. unsigned char p = 0;
  30. for (int i = 0; i < 8; ++i) {
  31. double x = x0 + (I*8+i)*dx;
  32. double y = y0 + j*dy;
  33.  
  34. int b = mandel_scalar1(x, y, maxIter);
  35. p = (p << 1) | b;
  36. }
  37. row[I] = p;
  38. }
  39. }
  40. }
  41.  
  42.  
  43.  
  44. static inline int iter_scalar2(double* pzr, double* pzi, double* pn2, const double* pcr, double ci) {
  45. for (int k = 0; k < 8; ++k) {
  46. double rr = pzr[k] * pzr[k];
  47. double ii = pzi[k] * pzi[k];
  48. double ri = pzr[k] * pzi[k];
  49.  
  50. pn2[k] = rr + ii;
  51.  
  52. pzr[k] = rr - ii + pcr[k];
  53. pzi[k] = ri + ri + ci;
  54. }
  55. }
  56.  
  57. static inline unsigned char mand8_scalar2(int to_prune, const double* pcr, double ci, int maxIter) {
  58. double pzr[8], pzi[8], pn2[8];
  59. for (int k = 0; k < 8; ++k) {
  60. pzr[k] = pcr[k];
  61. pzi[k] = ci;
  62. }
  63. int i = 0;
  64.  
  65. if (to_prune) {
  66. for (i = 0; i < maxIter-3; i += 4) {
  67. for (int j = 0; j < 4; ++j) {
  68. iter_scalar2(pzr, pzi, pn2, pcr, ci);
  69. }
  70. int do_break = 1;
  71. for (int k = 0; k < 8; ++k) {
  72. do_break &= !(pn2[k] < 4.);
  73. }
  74. if (do_break) return 0;
  75. }
  76. for (; i < maxIter; i++) {
  77. iter_scalar2(pzr, pzi, pn2, pcr, ci);
  78. }
  79. } else {
  80. for (i = 0; i < maxIter-5; i += 6) {
  81. for (int j = 0; j < 6; ++j) {
  82. iter_scalar2(pzr, pzi, pn2, pcr, ci);
  83. }
  84. }
  85. for (; i < maxIter; i++) {
  86. iter_scalar2(pzr, pzi, pn2, pcr, ci);
  87. }
  88. }
  89. unsigned char byte = 0;
  90. for (int k = 0; k < 8; ++k) {
  91. byte = (byte << 1) | (pn2[k] <= 4.);
  92. }
  93. return byte;
  94. }
  95.  
  96.  
  97. void mandelbrot_scalar2(double x0, double y0, double x1, double y1, int width, int height, int maxIter, unsigned char* output) {
  98. double dx = (x1 - x0) / width;
  99. double dy = (y1 - y0) / height;
  100.  
  101. double X[width];
  102. for (int i = 0; i < width; ++i) {
  103. X[i] = x0 + i * dx;
  104. }
  105.  
  106. #pragma omp parallel for default(none) firstprivate(y0, dy, width, height, maxIter) shared(output, X) schedule(guided)
  107. for (int j = 0; j < height; ++j) {
  108. unsigned char* row = output + j*(width/8);
  109. double y = y0 + j*dy;
  110. int to_prune = 0;
  111. for (int I = 0; I < width/8; ++I) {
  112. double* px = &X[I*8];
  113. unsigned char byte = mand8_scalar2(to_prune, px, y, maxIter);
  114. to_prune = !byte;
  115. row[I] = byte;
  116. }
  117. }
  118. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement