๐ English Abstract
This technical guide explores high-performance troubleshooting strategies for frame latency and memory bottlenecks encountered when deploying OpenCV CUDA pipelines on NVIDIA Jetson embedded platforms. Although Jetson features a Unified Memory Architecture (UMA), improper use of Zero-Copy allocations, cache invalidation overheads, and synchronous CPU-GPU memory staging can introduce severe processing lags. This article breaks down the inner workings of NVMM buffers, pinned host memory, and asynchronous CUDA streams, providing actionable C++ implementation patterns and profiling techniques using NVIDIA Nsight Systems.
1. ์๋ก : Jetson ์ํคํ ์ฒ์ OpenCV CUDA ํ์ดํ๋ผ์ธ์ ํจ์
NVIDIA Jetson(AGX Orin, Orin Nano, Xavier ๋ฑ) ์๋ฆฌ์ฆ๋ ์๋ฒ ๋๋ ์ฃ์ง(Edge AI) ํ๊ฒฝ์์ ๋ฐ์ด๋ ์ฐ์ฐ ์ฑ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ์ผ๋ฐ์ ์ธ PC ํ๊ฒฝ์ ์ธ์ฅ ๊ทธ๋ํฝ ์นด๋(Discrete GPU, dGPU) ์ํคํ ์ฒ๋ CPU์ ์์คํ ๋ฉ๋ชจ๋ฆฌ(System RAM)์ GPU์ VRAM์ด ๋ฌผ๋ฆฌ์ ์ผ๋ก ๋ถ๋ฆฌ๋์ด ์์ด PCIe ๋ฒ์ค๋ฅผ ํตํ ๋ช ์์ ๋ฐ์ดํฐ ์ ์ก์ด ํ์์ ์ ๋๋ค. ๋ฐ๋ฉด, NVIDIA Jetson ์๋ฆฌ์ฆ๋ **ํตํฉ ๋ฉ๋ชจ๋ฆฌ ์ํคํ ์ฒ(Unified Memory Architecture, UMA)**๋ฅผ ์ฑํํ์ฌ CPU์ GPU๊ฐ ๋ฌผ๋ฆฌ์ ์ผ๋ก ๋์ผํ LPDDR5/LPDDR4X DRAM์ ๊ณต์ ํฉ๋๋ค.
์ด ์ด๋ก ์ ๋ฐฐ๊ฒฝ ๋๋ฌธ์ ๋ง์ ์์ง๋์ด๋ค์ด "Jetson์์๋ ๋ฉ๋ชจ๋ฆฌ ๋ณต์ฌ ๋ณต์ก๋ ์์ด **Zero-Copy ๋ฉ๋ชจ๋ฆฌ ํ ๋น(Zero-Copy Memory Allocation)**์ ์ฌ์ฉํ๋ฉด ํ๋ ์ ์ง์ฐ(Frame Latency)์ด ์์ ํ ์ฌ๋ผ์ง ๊ฒ"์ด๋ผ๊ณ ๊ธฐ๋ํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ค์ ๊ฐ๋ฐ ํ์ฅ์์ OpenCV CUDA ๋ชจ๋(cv::cuda::GpuMat)์ ์ ์ฉํด ๋ณด๋ฉด, ์๊ธฐ์น ์์ ํ๋ ์ ๋๋กญ(Frame Drop)์ด๋ ๋ณต์ฌ ๋ณ๋ชฉ(Memory Copy Bottleneck), CPU-GPU ๋๊ธฐํ ๋ธ๋กํน ํ์์ผ๋ก ์ธํด 30 FPS์กฐ์ฐจ ์ ์งํ์ง ๋ชปํ๋ ํธ๋ฌ๋ธ์ํ
์ํฉ์ ์ง๋ฉดํ๊ฒ ๋ฉ๋๋ค.
๋ณธ ๊ธ์์๋ Jetson ์ฃ์ง ๋๋ฐ์ด์ค์์ OpenCV CUDA ํ์ดํ๋ผ์ธ ๊ตฌ์ถ ์ ๋ฐ์ํ๋ Zero-Copy ๋ฉ๋ชจ๋ฆฌ ๋ณ๋ชฉ์ ๊ทผ๋ณธ ์์ธ์ ์ํคํ ์ฒ ์์ค์์ ๋ถ์ํ๊ณ , ํ๋ ์ ์ง์ฐ์ ๊ทน๋จ์ ์ผ๋ก ์ค์ผ ์ ์๋ ์ค๋ฌด ์ต์ ํ ๋ฐฉ๋ฒ๋ก ์ ์ ์ํฉ๋๋ค.
2. Jetson ๋ฉ๋ชจ๋ฆฌ ์ํคํ ์ฒ์ Zero-Copy์ ์๋ ๋งค์ปค๋์ฆ
Zero-Copy ๋ฉ์ปค๋์ฆ์ ์ ํํ ํ์ ํ๊ธฐ ์ํด์๋ Jetson ์์คํ ์ ๋ฉ๋ชจ๋ฆฌ ๊ณ์ธต ๊ตฌ์กฐ์ **DMA(Direct Memory Access)**, ๊ทธ๋ฆฌ๊ณ ์บ์ ์ผ๊ด์ฑ(Cache Coherency)์ ์ดํดํด์ผ ํฉ๋๋ค.
2.1. Unified Memory vs Zero-Copy (Mapped Host Memory)
NVIDIA ์์คํ ์์ ๋ฉ๋ชจ๋ฆฌ ๊ณต์ ๋ฐฉ์์ ํฌ๊ฒ ๋ ๊ฐ์ง๋ก ๊ตฌ๋ถ๋ฉ๋๋ค:
- CUDA Unified Memory (
cudaMallocManaged): ํ์ด์ง ํดํธ(Page Fault) ๋ฉ์ปค๋์ฆ์ ๊ธฐ๋ฐ์ผ๋ก ํฉ๋๋ค. CPU๋ GPU๊ฐ ํด๋น ์ฃผ์์ ์ ๊ทผํ ๋ ๋ฐํ์์ด ๋์ ์ผ๋ก ํ์ด์ง๋ฅผ ๋ง์ด๊ทธ๋ ์ด์ ํ๊ฑฐ๋ ๋งตํ์ ๋ณ๊ฒฝํฉ๋๋ค. ์ฃผ์ ์ ๊ทผ ํจํด์ด ๋ถ๊ท์นํ ๊ฒฝ์ฐ ์ฌ๊ฐํ ํ์ด์ง ํดํธ ์ค๋ฒํค๋(Page Fault Overhead)๋ฅผ ์ ๋ฐํ ์ ์์ต๋๋ค. - Zero-Copy Memory (
cudaHostAllocMapped/ Pinned Memory): CPU์ ํธ์คํธ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ์ด์ง ์ ๊ธ(Page-Locked/Pinned) ์ํ๋ก ํ ๋นํ๊ณ , ํด๋น ๋ฉ๋ชจ๋ฆฌ์ ํฌ์ธํฐ๋ฅผ GPU ๋๋ฐ์ด์ค ์ฃผ์ ๊ณต๊ฐ์ ์ง์ ๋งคํ(cudaHostGetDevicePointer)ํฉ๋๋ค. GPU ์ฐ์ฐ ์ฅ์น๋ PCIe ๋ฒ์ค(๋๋ ๋ด๋ถ์ ์ฐ๊ฒฐ๋ AXI/NVLink ๋ฒ์ค)๋ฅผ ํตํด CPU ๋ฉ๋ชจ๋ฆฌ์ ์ง์ ๋ฐ์ดํฐ **์คํธ๋ฆฌ๋ฐ(Read/Write Streaming)**์ ์ํํฉ๋๋ค.
2.2. ์บ์ ์ผ๊ด์ฑ(Cache Coherency)๊ณผ Snooping ์ค๋ฒํค๋
Jetson ์ํคํ ์ฒ๋ CPU L1/L2 ์บ์์ GPU L2 ์บ์ ๊ฐ ์๋ฒฝํ ํ๋์จ์ด ์บ์ ์ผ๊ด์ฑ(Hardware Cache Coherency)์ ์์ ํ ์ง์ํ์ง ์๋ ์์ญ์ด ์กด์ฌํฉ๋๋ค. CPU๊ฐ Zero-Copy ๋ฉ๋ชจ๋ฆฌ์ ๋ฐ์ดํฐ๋ฅผ ์ธ ๊ฒฝ์ฐ, ๊ทธ ๋ฐ์ดํฐ๋ CPU ์บ์ ๋ผ์ธ(Cache Line)์ ๋จผ์ ๋์น๋ ์ ์์ต๋๋ค. GPU๊ฐ ์ด๋ฅผ ์ฆ์ ์ฝ์ผ๋ ค ํ๋ฉด CPU ์บ์ ํ๋ฌ์(Cache Flush)๋ ๋ฌดํจํ(Invalidation) ์์ ์ด ํธ๋ฆฌ๊ฑฐ๋๋ฉฐ ์ด ๊ณผ์ ์์ **์ค๋ํ(Snooping) ๋ณ๋ชฉ**์ด ๋ฐ์ํ์ฌ ์ฐ์ฐ ์ง์ฐ์ด ๊ฐ์ค๋ฉ๋๋ค.
3. OpenCV CUDA ํ์ดํ๋ผ์ธ์์์ ๋ณ๋ชฉ ์์ธ ํธ๋ฌ๋ธ์ํ (Edge Cases)
Jetson ๊ฐ๋ฐ์๋ค์ด OpenCV cv::cuda::GpuMat์ ๋ค๋ฃฐ ๋ ๋น๋ฒํ๊ฒ ์ ์ง๋ฅด๋ ์ค์์ ์์คํ
์ ์ธ ๋ณ๋ชฉ ์์ธ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
3.1. cv::cuda::GpuMat::upload()์ ์๋ฌต์ ๋์ผ ํฉํฐ ๋ฉ๋ชจ๋ฆฌ ๋ณต์ฌ
๊ฐ์ฅ ํํ ๋ฒํ๋ ์ค๋ฌด ์ค๋ฅ๋ ๊ธฐ์กด CPU ํ์ดํ๋ผ์ธ ์ฝ๋์ cv::Mat์ cv::cuda::GpuMat::upload() ํจ์๋ก ์ ๋ฌํ๋ ๊ฒ์
๋๋ค. Jetson์ด UMA ๊ตฌ์กฐ๋ผ ํ ์ง๋ผ๋, ์ผ๋ฐ cv::Mat์ ํ์ด์ง ๊ฐ๋ฅ ๋ฉ๋ชจ๋ฆฌ(Pageable Memory)์ ํ ๋น๋ฉ๋๋ค. CUDA ๋๋ผ์ด๋ฒ๋ ์ด๋ฅผ GPU๋ก ๋ณด๋ผ ๋ ๋ด๋ถ์ ์ผ๋ก ์์ ํ๋ ํํ ๋ฒํผ(Staging Buffer)๋ฅผ ์์ฑํ์ฌ memcpy๋ฅผ ๋จผ์ ์ํํ ๋ค DMA ์ ์ก์ ์ผ์ผํต๋๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก UMA ํ๊ฒฝ์์๋ ๋ถํ์ํ ๋ฉ๋ชจ๋ฆฌ ๋ณต์ฌ๊ฐ 2ํ ์ด์ ์ผ์ด๋ฉ๋๋ค.
3.2. NVMM (NVIDIA Multimedia API) ๋ฒํผ ๋งคํ ๋ฏธ์
GStreamer ๋๋ DeepStream ํ์ดํ๋ผ์ธ(nvarguscamerasrc, v4l2src)์ ์ฌ์ฉํ ๋ ํ๋์จ์ด ๋น๋์ค ๋์ฝ๋(NVDEC)๋ **NVMM(NVIDIA Multimedia Memory)** ์์ญ์ธ NvBufSurface ๋๋ NvBuffer๋ฅผ ์ถ๋ ฅํฉ๋๋ค. ์ด ๋ฒํผ๋ฅผ CPU ๋ฉ๋ชจ๋ฆฌ๋ก ํ ๋ฒ ๊ฐ์ ธ์๋ค๊ฐ ๋ค์ OpenCV CUDA๋ก ๋๊ธฐ๋ฉด ์์ฒญ๋ ๋ฐ์ดํฐ ๋ณ๋ชฉ์ด ๋ฐ์ํฉ๋๋ค. ํ๋์จ์ด ๋์ฝ๋์ ๋ฉ๋ชจ๋ฆฌ ๋งต ํฌ์ธํฐ(EGLImage ๋๋ Direct CUDA Pointer)๋ฅผ ์ถ์ถํ์ง ์๊ณ ์ค๊ฐ ๋ณํ ๊ณผ์ ์ ๊ฑฐ์น๋ ๊ฒ์ด ํ๋ ์ ๋๋กญ์ ์ฃผ์์ธ์
๋๋ค.
3.3. ๋๊ธฐํ ๋ธ๋กํน๊ณผ ์คํธ๋ฆผ(Stream) ๋ถ์ฌ
OpenCV CUDA API์ ๋๋ถ๋ถ์ ์คํธ๋ฆผ ์ธ์(cv::cuda::Stream)๋ฅผ ์ ๋ฌํ์ง ์์ผ๋ฉด ๊ธฐ๋ณธ ์คํธ๋ฆผ(Default/Null Stream) ์์์ ๋์ํฉ๋๋ค. ์ด๋ ๋ชจ๋ CUDA ์ปค๋ ํธ์ถ ์งํ **๋ฌต์์ ๋๊ธฐํ(Implicit Synchronization)**๋ฅผ ์ ๋ฐํ์ฌ, CPU ์ฐ์ฐ๊ณผ GPU ์ฐ์ฐ์ ํ์ดํ๋ผ์ด๋(Pipelining)์ด ํ๊ดด๋๊ณ GPU ์ฐ์ฐ ์ฅ์น๊ฐ Idle ์ํ์ ๋น ์ง๊ฒ ๋ฉ๋๋ค.
4. ์ค๋ฌด ์ต์ ํ ๊ตฌํ: Zero-Copy ๊ธฐ๋ฐ OpenCV CUDA ํ์ดํ๋ผ์ธ
์ด๋ฌํ ๋ฌธ์ ๋ฅผ ์์ ํ ํด์ํ๊ณ ์ง์ฐ ์๋(Zero-Latency) ๊ณ ์ฑ๋ฅ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ถํ๊ธฐ ์ํ C++ ์ค๋ฌด ์ฝ๋ ๋ชจ๋์ ์์ฑํด ๋ณด๊ฒ ์ต๋๋ค.
4.1. Zero-Copy Allocator๋ฅผ ํ์ฉํ GpuMat ์ง์ ๋งตํ
CPU์ GPU๊ฐ ๊ณต์ ํ๋ฉฐ ์บ์ ํ๋ฌ์ ์ค๋ฒํค๋๋ฅผ ์ต์ํํ๊ธฐ ์ํด cudaHostAllocWriteCombined ํ๋๊ทธ๋ฅผ ํ์ฉํด Pinned Memory๋ฅผ ์ง์ ๋์ ํ ๋นํ๊ณ , ํค๋๋ง cv::Mat๊ณผ cv::cuda::GpuMat์ ๋์ ๋งคํํ๋ ๋ฐฉ์์
๋๋ค.
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/cudaimgproc.hpp>
#include <cuda_runtime.h>
class ZeroCopyBuffer {
public:
void* host_ptr = nullptr;
void* device_ptr = nullptr;
size_t buffer_size = 0;
cv::Mat host_mat;
cv::cuda::GpuMat gpu_mat;
ZeroCopyBuffer(int width, int height, int type) {
size_t elem_size = CV_ELEM_SIZE(type);
buffer_size = width * height * elem_size;
// 1. WriteCombined ํ๋๊ทธ๋ฅผ ์ฌ์ฉํ์ฌ CPU ์บ์ ์ค์ผ ๋ฐฉ์ง ๋ฐ GPU ์ฝ๊ธฐ ์๋ ๊ทน๋ํ
cudaError_t err = cudaHostAlloc(&host_ptr, buffer_size, cudaHostAllocMapped | cudaHostAllocWriteCombined);
if (err != cudaSuccess) {
std::cerr << "cudaHostAlloc Failed: " << cudaGetErrorString(err) << std::endl;
return;
}
// 2. GPU์ฉ ๋๋ฐ์ด์ค ํฌ์ธํฐ ์ทจ๋ (Jetson UMA ํ๊ฒฝ์์๋ ๋์ผ ์ฃผ์ ๊ณต๊ฐ์ผ๋ก ๋งคํ๋จ)
cudaHostGetDevicePointer(&device_ptr, host_ptr, 0);
// 3. ๋ณ๋์ ๋ฉ๋ชจ๋ฆฌ ๋ณต์ฌ ์์ด ๋์ผํ ๋ฉ๋ชจ๋ฆฌ ๋ฒํผ๋ฅผ ๋ฐ๋ผ๋ณด๋ Header ๋ฐ์ธ๋ฉ
host_mat = cv::Mat(height, width, type, host_ptr);
gpu_mat = cv::cuda::GpuMat(height, width, type, device_ptr);
}
~ZeroCopyBuffer() {
if (host_ptr) {
cudaFreeHost(host_ptr);
}
}
};
4.2. NVMM ๋ฒํผ(NvBufSurface)๋ก๋ถํฐ CUDA ๋ฉ๋ชจ๋ฆฌ Direct Zero-Copy Interop
์นด๋ฉ๋ผ ํ๋ ์ ์
๋ ฅ์ ๋ฐ๋ ๊ฒฝ์ฐ GStreamer/JetPack SDK์ NvBufSurface ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ Direct CUDA ํฌ์ธํฐ๋ก ๋ณํํ์ฌ cv::cuda::GpuMat์ผ๋ก ๋ํํ๋ ์ต์ ํ ํจํด์
๋๋ค.
#include "nvbufsurface.h"
#include "nvbufsurftransform.h"
#include <opencv2/cudaimgproc.hpp>
// GStreamer pad probe ๋๋ Buffer Callback ๋ด๋ถ
void process_nvmm_buffer(NvBufSurface* surf, int frame_idx, cv::cuda::Stream& stream) {
NvBufSurfaceParams *params = &surf->surfaceList[frame_idx];
// NvBufSurface ๋งตํ (CUDA ๊ฐ์ ์ฃผ์ ํ์ธ)
if (surf->memType == NVBUF_MEM_SURFACE_ARRAY || surf->memType == NVBUF_MEM_HANDLE) {
NvBufSurfaceMap(surf, frame_idx, 0, NVBUF_MAP_READ_WRITE);
NvBufSurfaceSyncForDevice(surf, frame_idx, 0); // ์บ์ sync
// CUDA ํฌ์ธํฐ ์ง์ ํ๋ (๋ฉ๋ชจ๋ฆฌ Copy 0ํ)
void* cuda_dev_ptr = params->dataPtr;
// NV12 ๋๋ YUV420 ํํ์ NVMM ๋ฐ์ดํฐ๋ฅผ GpuMat์ผ๋ก ๋ํ
// Height๋ Y์ฑ๋ + UV์ฑ๋๋ก ์ธํด 1.5๋ฐฐ ์ค์
cv::cuda::GpuMat nv12_gmat(params->height * 3 / 2, params->width, CV_8UC1, cuda_dev_ptr, params->pitch);
cv::cuda::GpuMat bgr_gmat;
// CUDA ์ปค๋์ ํตํด GPU ๋ด๋ถ์์ ์ง์ BGR ์์ ๊ณต๊ฐ ๋ณํ ์ํ (๋น๋๊ธฐ)
cv::cuda::cvtColor(nv12_gmat, bgr_gmat, cv::COLOR_YUV2BGR_NV12, 3, stream);
// ์ดํ OpenCV CUDA ๊ฐ๊ณต ์๊ณ ๋ฆฌ์ฆ ์ํ...
NvBufSurfaceUnMap(surf, frame_idx, 0);
}
}
4.3. ๋น๋๊ธฐ ํ์ดํ๋ผ์ธ(Asynchronous Execution Stream) ๊ตฌ์ฑ
๋จ์ผ ํ๋ ์ ์ฒ๋ฆฌ ์ง์ฐ ์๊ฐ์ ์ค์ด๋ ค๋ฉด ๋น๋๊ธฐ ์คํธ๋ฆผ์ ์ฌ์ฉํ์ฌ '์นด๋ฉ๋ผ ํ๋ ์ ์บก์ฒ(DMA Host)', 'OpenCV CUDA ์ฐ์ฐ(GPU)', '๊ฒฐ๊ณผ ์ถ๋ก ๋ฐ ์ธ์ฝ๋ฉ(NVDLA/TensorRT)'์ ํํ(Ping-Pong) ๋ฉํฐ ๋ฒํผ ๊ตฌ์กฐ๋ก ์ค์ฒฉ(Overlap)์์ผ์ผ ํฉ๋๋ค.
์ฝ๋์์ ๋ชจ๋ cv::cuda ํจ์ ํธ์ถ ์ stream ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ๋ฉด CPU๋ GPU ์ฐ์ฐ ์๋ฃ๋ฅผ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ๊ณง๋ฐ๋ก ๋ค์ ํ๋ ์ ๋์ฝ๋ฉ์ ์งํํ ์ ์์ด ํ๋ ์๋ฅ (FPS)์ด ๋น์ฝ์ ์ผ๋ก ์์นํฉ๋๋ค.
5. Nsight Systems ๊ธฐ๋ฐ ์ฑ๋ฅ ํ๋กํ์ผ๋ง ๋ฐ ํธ๋ฌ๋ธ์ํ ์ ์ฐจ
์ต์ ํ ์์
์ ํ์ ์ค์ ๋ณ๋ชฉ ์ง์ ์ ์๊ฐ์ ์ผ๋ก ๊ฒ์ฆํ๋ ค๋ฉด NVIDIA ๊ณต์ ํ๋กํ์ผ๋ฌ์ธ **Nsight Systems (nsys)**๋ฅผ ํ์ฉํด์ผ ํฉ๋๋ค.
5.1. nsys ํ์๋ผ์ธ ์์ง ๋ช ๋ น
# Jetson ํ๊ฒ ์ฅ๋น์์ ํ๋กํ์ผ๋ง ๋ฐ์ดํฐ ์์ง
nsys profile --trace=cuda,nvtx,osrt,gstreamer \
--output=jetson_opencv_trace \
--delay=5 --duration=10 \
./your_opencv_app
5.2. ํ์๋ผ์ธ ๋ถ์ ์ ์ ๊ฒํด์ผ ํ 3๊ฐ์ง ํต์ฌ ์งํ
cudaMemcpyAsync(Host to Device / Device to Host) ๋ธ๋ก ํฌ๊ธฐ: ํ์๋ผ์ธ์์ ํฐ ํญ์cudaMemcpy๋ฒ์ฃผ๊ฐ ๋ณด์ธ๋ค๋ฉด Zero-Copy๊ฐ ์คํจํ๊ณ ๋ช ์์ ๋ฉ๋ชจ๋ฆฌ ์ฌ๋ณต์ฌ๊ฐ ์ผ์ด๋๋ ์ฆ๊ฑฐ์ ๋๋ค.- CUDA Stream ๊ฐ Gap (๋น ๊ณต๊ฐ): GPU ์ปค๋๊ณผ ์ปค๋ ์ฌ์ด์ ๋น์ด์๋ ์๊ฐ์ด ๊ธธ๋ค๋ฉด CPU ์ธก์
cv::Mat์์ฑ ๋ฉ๋ชจ๋ฆฌ ํ ๋น ๋ณ๋ชฉ์ด๋,cudaStreamSynchronize()ํธ์ถ๋ก ์ธํ CPU ๋ธ๋กํน์ด ๋ฐ์ํ๋ ์ง์ ์ ๋๋ค. - Unified Memory Page Fault Event: Trace ํ์๋ผ์ธ ํ๋จ์
Gpu Page Fault์ด๋ฒคํธ ๋ ์ฝ๋๊ฐ ๋ค์ ์ฐํ๋ค๋ฉด Managed Memory ์ฌ์ฉ ์กฐ๊ฑด์ ์ฌ๊ฒํ ํ๊ณ Pinned Mapped Memory ๋ฐฉ์์ผ๋ก ์ ํํด์ผ ํฉ๋๋ค.
6. ๊ฒฐ๋ก : Jetson ๋๋ฐ์ด์ค์ฉ ์ค๋ฌด ๊ฒ์ฆ ์ฒดํฌ๋ฆฌ์คํธ
NVIDIA Jetson ํ๋ซํผ ์์์ OpenCV CUDA ํ์ดํ๋ผ์ธ์ ๊ตฌ์ถํ ๋ ๋ณ๋ชฉ ์๋ ์ด๊ณ ์ ์ค์๊ฐ ์ฒ๋ฆฌ๋ฅผ ๋ฌ์ฑํ๊ธฐ ์ํด ๋ค์ ํต์ฌ ์ฒดํฌ๋ฆฌ์คํธ๋ฅผ ๋ฐ๋์ ์ค๋ฌด์ ์ ์ฉํ์ญ์์ค.
| ํญ๋ชฉ | ๊ถ์ฅ ์ค์ / ๊ธฐ๋ฒ | ์ต์ ํ ํจ๊ณผ |
|---|---|---|
| ๋ฉ๋ชจ๋ฆฌ ํ ๋น | cudaHostAllocWriteCombined + cudaHostGetDevicePointer |
CPU/GPU ๊ฐ ๋ช ์์ ๋ณต์ฌ ์์ ์ ๊ฑฐ ๋ฐ CPU ์บ์ ํ๋ฌ์ ๋ฐฉ์ง |
| ์นด๋ฉ๋ผ/๋์ฝ๋ฉ | GStreamer NVMM (NvBufSurface) direct pointer mapping |
๋น๋์ค ๋์ฝ๋ -> CUDA ์ฐ์ฐ ๊ฐ Zero-Copy ๋ฌ์ฑ |
| CUDA ์คํ | cv::cuda::Stream ๋น๋๊ธฐ ๊ฐ์ฒด ์ ํ |
CPU-GPU Pipeline Overlapping์ ํตํ ํ๋ ์ ์ฒ๋ฆฌ ์ง์ฐ ์ต์ํ |
| ์ฑ๋ฅ ์ธก์ | NVIDIA Nsight Systems (nsys) ํ์๋ผ์ธ ์ถ์ |
๋ณ๋ชฉ ๊ตฌ๊ฐ(Memcpy, CPU Blocking) ์์น์ ๋ถ์ ๋ฐ ๊ฒ์ฆ |
Jetson์ ์ํคํ ์ฒ์ ํน์ฑ์ธ UMA๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ํ์ฉํ๊ณ , ์๋ฌต์ ์ธ ๋ฉ๋ชจ๋ฆฌ ๋ณต์ฌ ๋ฐ ์บ์ ๋๊ธฐํ ์ด์๋ฅผ ์ ์ดํจ์ผ๋ก์จ ์ฃ์ง AI ํ๊ฒฝ์์๋ ์ต๊ณ ์์ค์ FPS์ ์ต์ ์ ํ๋ ์ ์ง์ฐ ์๊ฐ์ ํ๋ณดํ ์ ์์ต๋๋ค.