1. cuda 설치 후, 하단의 소스를 nvcc 로 컴파일하여 실행
(nvcc -o 실행파일명 소스파일명)
2. nvtop, nvidia-smi 로 자원 사용량 모니터링
#include <stdio.h>
#include <cuda_runtime.h>
#include <thread>
#include <vector>
#define N 1024 // 매트릭스 크기 (N x N)
#define NUM_GPUS 2 // 사용할 GPU 개수
#define REPEAT 1000 // 반복 횟수
// CUDA 커널: 매트릭스 곱셈
__global__ void matrixMultiply(float *a, float *b, float *c, int n) {
int row = blockIdx.y * blockDim.y + threadIdx.y;
int col = blockIdx.x * blockDim.x + threadIdx.x;
if (row < n && col < n) {
float sum = 0.0f;
for (int i = 0; i < n; i++) {
sum += a[row * n + i] * b[i * n + col];
}
c[row * n + col] = sum;
}
}
// GPU 작업을 수행하는 함수
void gpuTask(int gpu, float *h_a, float *h_b, float *h_c, int rowsPerGPU) {
int size = N * N * sizeof(float);
// 디바이스 메모리 할당
float *d_a, *d_b, *d_c;
cudaSetDevice(gpu);
cudaMalloc((void **)&d_a, rowsPerGPU * N * sizeof(float));
cudaMalloc((void **)&d_b, size);
cudaMalloc((void **)&d_c, rowsPerGPU * N * sizeof(float));
// 데이터 복사: 호스트 -> 디바이스
cudaMemcpy(d_a, h_a + gpu * rowsPerGPU * N, rowsPerGPU * N * sizeof(float), cudaMemcpyHostToDevice);
cudaMemcpy(d_b, h_b, size, cudaMemcpyHostToDevice);
// 커널 실행 설정
dim3 threadsPerBlock(16, 16);
dim3 blocksPerGrid((N + threadsPerBlock.x - 1) / threadsPerBlock.x,
(rowsPerGPU + threadsPerBlock.y - 1) / threadsPerBlock.y);
// REPEAT번 반복 실행
for (int i = 0; i < REPEAT; i++) {
matrixMultiply<<<blocksPerGrid, threadsPerBlock>>>(d_a, d_b, d_c, N);
cudaDeviceSynchronize();
}
// 결과 복사: 디바이스 -> 호스트
cudaMemcpy(h_c + gpu * rowsPerGPU * N, d_c, rowsPerGPU * N * sizeof(float), cudaMemcpyDeviceToHost);
// 디바이스 메모리 해제
cudaFree(d_a);
cudaFree(d_b);
cudaFree(d_c);
}
int main() {
int size = N * N * sizeof(float);
// 각 GPU에 할당할 행의 수
int rowsPerGPU = N / NUM_GPUS;
// 호스트 메모리 할당
float *h_a = (float *)malloc(size);
float *h_b = (float *)malloc(size);
float *h_c = (float *)malloc(size);
// 입력 데이터 초기화
for (int i = 0; i < N * N; i++) {
h_a[i] = 1.0f;
h_b[i] = 1.0f;
}
// GPU 작업을 스레드로 실행
std::vector<std::thread> threads;
for (int gpu = 0; gpu < NUM_GPUS; gpu++) {
threads.emplace_back(gpuTask, gpu, h_a, h_b, h_c, rowsPerGPU);
}
// 모든 스레드 종료 대기
for (auto &t : threads) {
t.join();
}
// 결과 확인 (첫 번째 값만 출력)
printf("Result of c[0]: %f\n", h_c[0]);
// 호스트 메모리 해제
free(h_a);
free(h_b);
free(h_c);
return 0;
}