util.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /* Copyright 2018 Canaan Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. #ifndef _BSP_UTIL_H
  16. #define _BSP_UTIL_H
  17. #include <stdint.h>
  18. #if defined(__riscv)
  19. #include "encoding.h"
  20. #endif
  21. #ifdef __cplusplus
  22. extern "C" {
  23. #endif
  24. #if defined(__GNUC__)
  25. #pragma GCC diagnostic ignored "-Wunused-parameter"
  26. #pragma GCC diagnostic ignored "-Wunused-function"
  27. #endif
  28. /**
  29. * --------------------------------------------------------------------------
  30. * Macros
  31. * Set HOST_DEBUG to 1 if you are going to compile this for a host
  32. * machine (ie Athena/Linux) for debug purposes and set HOST_DEBUG
  33. * to 0 if you are compiling with the smips-gcc toolchain.
  34. */
  35. #ifndef HOST_DEBUG
  36. #define HOST_DEBUG 0
  37. #endif
  38. /**
  39. * Set PREALLOCATE to 1 if you want to preallocate the benchmark
  40. * function before starting stats. If you have instruction/data
  41. * caches and you don't want to count the overhead of misses, then
  42. * you will need to use preallocation.
  43. */
  44. #ifndef PREALLOCATE
  45. #define PREALLOCATE 0
  46. #endif
  47. #define static_assert(cond){ \
  48. switch(0){ \
  49. case 0 : case !!(long)(cond):; } }
  50. #define stringify_1(s) #s
  51. #define stringify(s) stringify_1(s)
  52. #define stats(code, iter) \
  53. do \
  54. { \
  55. unsigned long _c = -read_cycle(), _i = -read_csr(minstret); \
  56. code; \
  57. _c += read_cycle(), _i += read_csr(minstret); \
  58. if(cid == 0) \
  59. printf("\r\n%s: %ld cycles, %ld.%ld cycles/iter, %ld.%ld CPI\r\n", \
  60. stringify(code), _c, _c / iter, 10 * _c / iter % 10, _c / _i, 10 * _c / _i % 10); \
  61. } while(0)
  62. /**
  63. * Set SET_STATS to 1 if you want to carve out the piece that actually
  64. * does the computation.
  65. */
  66. #if HOST_DEBUG
  67. #include <stdio.h>
  68. static void setStats(int enable)
  69. {
  70. }
  71. #else
  72. extern void setStats(int enable);
  73. #endif
  74. static void printArray(const char name[], int n, const int arr[])
  75. {
  76. #if HOST_DEBUG
  77. int i;
  78. printf(" %10s :", name);
  79. for(i = 0; i < n; i++)
  80. printf(" %3d ", arr[i]);
  81. printf("\r\n");
  82. #endif
  83. }
  84. static void printDoubleArray(const char name[], int n, const double arr[])
  85. {
  86. #if HOST_DEBUG
  87. int i;
  88. printf(" %10s :", name);
  89. for(i = 0; i < n; i++)
  90. printf(" %g ", arr[i]);
  91. printf("\r\n");
  92. #endif
  93. }
  94. static int verify(int n, const volatile int *test, const int *verify)
  95. {
  96. int i;
  97. /* Unrolled for faster verification */
  98. for(i = 0; i < n / 2 * 2; i += 2)
  99. {
  100. int t0 = test[i], t1 = test[i + 1];
  101. int v0 = verify[i], v1 = verify[i + 1];
  102. if(t0 != v0)
  103. return i + 1;
  104. if(t1 != v1)
  105. return i + 2;
  106. }
  107. if(n % 2 != 0 && test[n - 1] != verify[n - 1])
  108. return n;
  109. return 0;
  110. }
  111. static int verifyDouble(int n, const volatile double *test, const double *verify)
  112. {
  113. int i;
  114. /* Unrolled for faster verification */
  115. for(i = 0; i < n / 2 * 2; i += 2)
  116. {
  117. double t0 = test[i], t1 = test[i + 1];
  118. double v0 = verify[i], v1 = verify[i + 1];
  119. int eq1 = t0 == v0, eq2 = t1 == v1;
  120. if(!(eq1 & eq2))
  121. return i + 1 + eq1;
  122. }
  123. if(n % 2 != 0 && test[n - 1] != verify[n - 1])
  124. return n;
  125. return 0;
  126. }
  127. static void __attribute__((noinline)) barrier(int ncores)
  128. {
  129. static volatile int sense = 0;
  130. static volatile int count = 0;
  131. static __thread int threadsense;
  132. __sync_synchronize();
  133. threadsense = !threadsense;
  134. if(__sync_fetch_and_add(&count, 1) == ncores - 1)
  135. {
  136. count = 0;
  137. sense = threadsense;
  138. } else
  139. {
  140. while(sense != threadsense)
  141. ;
  142. }
  143. __sync_synchronize();
  144. }
  145. static uint64_t lfsr(uint64_t x)
  146. {
  147. uint64_t bit = (x ^ (x >> 1)) & 1;
  148. return (x >> 1) | (bit << 62);
  149. }
  150. #if defined(__GNUC__)
  151. #pragma GCC diagnostic warning "-Wunused-parameter"
  152. #pragma GCC diagnostic warning "-Wunused-function"
  153. #endif
  154. #ifdef __cplusplus
  155. }
  156. #endif
  157. #endif /* _BSP_UTIL_H */