| 216 | } |
| 217 | |
| 218 | void mem_bench() { |
| 219 | constexpr size_t N_THREADS = 32; |
| 220 | constexpr size_t MB_PER_THREAD = 1024; |
| 221 | constexpr size_t ELS_PER_THREAD = (MB_PER_THREAD * 1024 * 1024) / sizeof(float); |
| 222 | constexpr size_t N = N_THREADS * ELS_PER_THREAD; |
| 223 | |
| 224 | std::cout << "Using " << N_THREADS << " threads" << std::endl; |
| 225 | std::cout << "Allocating " << N_THREADS * MB_PER_THREAD << " MB (" << N << " floats)" << std::endl; |
| 226 | float* data = allocateAlignedArray(N); |
| 227 | |
| 228 | std::cout << "Filling data..." << std::endl; |
| 229 | #pragma omp parallel for num_threads(N_THREADS) |
| 230 | for (size_t i = 0; i < N_THREADS; i++) { |
| 231 | fill_random(data + i * ELS_PER_THREAD, ELS_PER_THREAD, (unsigned long)i); |
| 232 | } |
| 233 | std::cout << "Running memory bandwidth test..." << std::endl; |
| 234 | |
| 235 | float totalSum = 0.0; |
| 236 | uint64_t start = get_timestamp_ms(); |
| 237 | #pragma omp parallel for simd reduction(+:totalSum) schedule(guided) aligned(data: 64) num_threads(N_THREADS) |
| 238 | for (size_t i = 0; i < N; i++) { |
| 239 | totalSum += data[i]; |
| 240 | } |
| 241 | |
| 242 | uint64_t end = get_timestamp_ms(); |
| 243 | float elapsed_s = (end - start) / 1000.0; |
| 244 | float mb_per_s = N_THREADS * MB_PER_THREAD / elapsed_s; |
| 245 | |
| 246 | std::cout << "Total sum: " << totalSum << std::endl; |
| 247 | std::cout << "Elapsed time: " << elapsed_s << " s" << std::endl; |
| 248 | std::cout << "Memory bandwidth: " << mb_per_s << " MB/s" << std::endl; |
| 249 | } |
| 250 | |
| 251 | // 64 is the typical cache line size |
| 252 | struct alignas(64) ThreadData { |
no test coverage detected