반응형
안녕하세요! 지난 글에서는 OpenCL 커널 작성법과 빌드 과정을 살펴보았습니다. 이제 커널에서 다룰 데이터가 어떻게 GPU나 CPU 디바이스 메모리에 올라가는지, 즉 OpenCL 메모리 모델과 그 핵심 요소인 버퍼(Buffer)와 이미지(Image)에 대해 알아볼 차례예요. 또한 커널에 파라미터(인자)를 전달하는 다양한 패턴에 대해서도 간단히 짚어보겠습니다.이번 글에서는 다음 내용을 다룹니다.OpenCL 메모리 모델 개요버퍼(Buffer)와 이미지(Image)의 특징과 사용 예커널 파라미터 설정 방법 심화CUDA의 메모리 관리 방식과 비교추가 참고 자료 (유튜브)1. OpenCL 메모리 모델 개요OpenCL 프로그램에서는 호스트(Host)가 디바이스(Device)에 연산을 시킵니다. 이 때, 데이터를 ..
지난 글에서는 2D 데이터 처리와 비동기 스트림(Asynchronous Streams)을 통해 Host와 Device 간 연산이 겹칠 수 있음을 확인했습니다. 이제는 GPU 메모리 계층을 살짝 들여다보고, 성능 최적화를 위해 왜 이러한 구조가 존재하는지 알아볼 차례입니다. 오늘 다룰 주제는 Shared Memory와 Constant Memory라는 특별한 메모리 공간들입니다. 이들은 단순한 글로벌 메모리(Global Memory) 접근보다 훨씬 더 빠르거나 특정 상황에서 효율적인 접근을 가능하게 해줍니다.메모리 계층 구조 이해하기GPU 메모리는 단순하지 않습니다. 성능을 극대화하기 위해 다양한 메모리 종류가 존재합니다.Global Memory(전역 메모리): 우리가 지금까지 cudaMalloc로 할당한 ..
C++23에서는 범위(Range) 라이브러리를 더욱 강력하고 유연하게 만들기 위해 다양한 뷰(View) 어댑터가 추가되었습니다. 그중 하나인 std::views::stride는 입력 범위에서 일정한 간격으로 원소를 선택하여 부분 범위를 구성하는 뷰 어댑터입니다. 이를 통해 예를 들어 [1,2,3,4,5,6,7,8] 범위에서 stride(3)를 적용하면 [1,4,7]와 같이 매 3번째 원소를 추출할 수 있습니다. 이번 글에서는 std::views::stride의 개념과 사용법, 그리고 이전 방식과 비교하여 어떠한 개선점을 제공하는지 알아보겠습니다. std::views::stride란 무엇인가요?std::views::stride(n)는 입력 범위에서 시작 원소를 포함해 매 n번째 원소를 선택하는 뷰 어댑터입..
이번 글에서는 지금까지 배운 스레드/블록/그리드 개념을 2차원 데이터에 적용하고, GPU의 비동기(Asynchronous) 기능을 살짝 맛보며 최적화를 향한 첫걸음을 내딛어보겠습니다. 이미지 처리나 행렬 연산 같은 2D 데이터 처리는 실제 GPU 활용 분야에서 매우 흔하고도 중요한 영역입니다. 또한 비동기 스트림을 활용하면 Host와 Device 사이의 작업을 겹치게 만들어 전체 처리 시간을 단축할 수 있다는 점을 알아볼 것입니다.2D 데이터 처리를 위한 블록/그리드 설정지금까지는 1차원 데이터(예: 벡터)에 대한 처리를 주로 다뤘습니다. 하지만 이미지(2D 배열)나 행렬을 다룬다면 2차원적으로 스레드와 블록을 배치하는 것이 직관적일 수 있습니다.2D 스레드 인덱스 계산 예제예를 들어, M x N 크기의..
안녕하세요! 지난 글에서 OpenCL 플랫폼과 디바이스 개념을 이해하고, 원하는 디바이스를 선택하는 방법까지 살펴봤습니다. 이제 본격적으로 커널(Kernel) 작성과 빌드 과정을 알아볼 차례예요. OpenCL 커널은 실제로 GPU나 CPU 등 디바이스에서 병렬 실행되는 코드로, 우리가 가속하고 싶은 연산의 핵심 부분이라고 할 수 있죠.이번 글에서는 다음 내용을 다룹니다.OpenCL 커널 기본 문법 소개호스트 코드에서 커널 빌드 방법 복습 및 확장인자 전달 및 메모리 관리 구조 이해CUDA 커널과 비교해 보는 코드 작성 차이점참고할만한 유튜브 자료 링크앞선 글에서 kernel.cl 파일 안에 간단한 add_one 커널을 작성해봤는데, 이번 글에서는 이보다 조금 더 다양한 형태의 커널 코드를 다뤄보면서 기본..
C++23에서는 표준 라이브러리에 std::spanstream 계열의 클래스 템플릿이 추가되어, 메모리 상의 연속 구역(spans)을 스트림처럼 다룰 수 있는 편리한 방법을 제공하게 되었습니다. 기존에 std::stringstream를 통해 문자열 기반 버퍼를 다루었다면, 이제는 std::span을 이용하여 메모리 버퍼를 입출력 스트림으로 다룰 수 있으며, 이를 통해 메모리에 이미 존재하는 데이터에 대해 스트림 연산을 간편히 적용할 수 있습니다. 이번 글에서는 std::spanstream, std::ispanstream, std::ospanstream의 개념과 사용법, 그리고 이전 방식과 비교하여 어떤 점이 개선되었는지 알아보겠습니다.std::spanstream란 무엇인가요?C++23에서 추가된 헤더에..
C++23에서는 범위(Range) 라이브러리를 풍성하게 하는 새로운 뷰(View) 어댑터들이 다양하게 추가되었습니다. 그중 하나가 바로 std::views::split_when 인데, 이 뷰 어댑터는 std::views::split와 유사한 역할을 하지만, 단순한 구분 문자나 구분 값이 아닌 **사용자 정의 조건자(predicate)**에 따라 범위를 동적으로 분할할 수 있습니다. 이를 통해 보다 유연하게 범위를 나누고, 특정 패턴이나 조건을 만족하는 지점마다 분리하는 로직을 간결하고 직관적으로 표현할 수 있습니다. 이번 글에서는 std::views::split_when의 개념과 사용법, 그리고 이전 방식과 비교하여 어떤 점이 개선되었는지 알아보겠습니다.std::views::split_when란 무엇인가..
C++23에서는 범위(Range) 라이브러리에 편의성과 가독성을 높이는 유용한 알고리즘들이 추가되었습니다. 특히 std::ranges::starts_with, std::ranges::ends_with, std::ranges::contains 세 가지 함수는 시퀀스를 다룰 때 흔히 필요한 패턴을 간결하고 명확하게 표현할 수 있도록 돕습니다. 이를 통해 문자열이나 컨테이너에서 특정 접두사/접미사 존재 여부나 특정 원소 포함 여부를 직관적으로 확인할 수 있습니다. 이번 글에서는 std::ranges::starts_with, std::ranges::ends_with, std::ranges::contains의 개념과 사용법, 그리고 이전 버전과 비교하여 어떤 점이 개선되었는지 알아보겠습니다.std::ranges:..
C++11부터 열거형(enum)은 enum class를 통해 타입 안전한 열거형을 지원하면서 강타입 열거형(strongly typed enum)을 도입했습니다. 하지만 여전히 열거형 값을 기반 정수 타입으로 변환할 때는 캐스팅(static_cast 등)을 수동으로 해야 했습니다. C++23에서는 이러한 불편함을 줄이기 위해 std::to_underlying 함수를 도입하였습니다. 이를 통해 강타입 열거형 값을 기저 타입(underlying type)으로 쉽게 변환할 수 있습니다. 이번 글에서는 std::to_underlying의 개념과 사용법, 그리고 이전 버전과 비교하여 어떠한 개선점을 제공하는지 알아보겠습니다.std::to_underlying란 무엇인가요?std::to_underlying 함수는 C+..
C++23에서는 범위(Range) 라이브러리에 다양한 뷰(View) 어댑터가 추가되어, 데이터 처리 파이프라인을 더욱 간결하고 표현력 있게 만들 수 있습니다. 그중 하나인 std::views::slide는 입력 범위에 대해 슬라이딩 윈도우(sliding window)를 적용하는 뷰 어댑터입니다. 이를 통해 고정 크기의 창(window)을 범위를 따라 이동시키면서 각 위치에서의 부분 범위를 쉽게 얻을 수 있습니다.이번 글에서는 std::views::slide의 개념과 사용법, 그리고 이전 방식과 비교하여 어떠한 개선점을 제공하는지 알아보겠습니다. std::views::slide란 무엇인가요?std::views::slide(n)는 입력 범위에 대해 길이 n의 윈도우를 순회하면서, 각 위치에서 길이 n짜리의 ..