AI

[CUDA] 동작/부하 테스트 샘플

Lawmin 2024. 12. 31. 09:39

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;
}