workshopgpu/cpp_single/main.cpp
2025-09-06 09:41:18 +05:30

66 lines
1.9 KiB
C++

#include <algorithm>
#include <chrono>
#include <cmath>
#include <cstdint>
#include <iostream>
#include <random>
#include <string>
#include <vector>
static void init_vec(std::vector<float> &v, uint64_t seed) {
std::mt19937 rng(static_cast<uint32_t>(seed));
std::uniform_real_distribution<float> dist(-1.0f, 1.0f);
for (auto &x : v) x = dist(rng);
}
int main(int argc, char **argv) {
size_t N = 100000000; // 1e8 by default (~400 MB across 4 arrays)
int iters = 10;
if (argc >= 2) N = static_cast<size_t>(std::stoull(argv[1]));
if (argc >= 3) iters = std::stoi(argv[2]);
std::vector<float> A(N), B(N), C(N), D(N), E(N);
init_vec(A, 1);
init_vec(B, 2);
init_vec(C, 3);
// Warmup
volatile float sink = 0.0f;
for (size_t i = 0; i < std::min<size_t>(N, 1000); ++i) {
float d = A[i] + B[i];
float e = d * C[i] + B[i];
sink += e;
}
auto start = std::chrono::high_resolution_clock::now();
double sum_result = 0.0;
for (int it = 0; it < iters; ++it) {
for (size_t i = 0; i < N; ++i) {
D[i] = A[i] + B[i];
}
for (size_t i = 0; i < N; ++i) {
E[i] = D[i] * C[i] + B[i];
}
double local_sum = 0.0;
for (size_t i = 0; i < N; ++i) {
local_sum += static_cast<double>(E[i]);
}
sum_result += local_sum;
}
auto end = std::chrono::high_resolution_clock::now();
double ms = std::chrono::duration<double, std::milli>(end - start).count();
// Bytes moved (approx): reads A,B then D,C,B, and write D,E each iter
// Reads: A,B,D,C,B ~ 5N floats; Writes: D,E ~ 2N floats => 7N * 4 bytes
double bytes_per_iter = 7.0 * N * sizeof(float);
double gbps = (bytes_per_iter * iters) / (ms / 1000.0) / 1e9;
std::cout << "CPP single-threaded\n";
std::cout << "N=" << N << " iters=" << iters << "\n";
std::cout << "time_ms=" << ms << "\n";
std::cout << "throughput_GBps=" << gbps << "\n";
std::cout << "result=" << sum_result << "\n";
return (sink == 12345.678f) ? 0 : 0; // prevent optimizing away
}