본문 바로가기

Tech

(593)
[CUDA] 두 1차원 벡터 덧셈 연산을 CUDA로 프로그래밍 해보자! 해당 포스팅은 AI와 NVIDIA에서 공식적으로 게시하는 문서인 CUDA Programming Guide 문헌을 기반으로 만들어졌음을 알립니다. 개인적으로 최대한 엄밀하게 검증을 거쳤으며 혹여나 잘못된 내용이 있다라고 판단되면 적극 피드백 부탁드립니다. *앞으로, CPU 장치를 호스트 장치로, GPU 장치를 디바이스 장치로 부르도록 하겠다.이번 포스팅에서는 본격적으로 CUDA 프로그래밍을 통해서 벡터 연산을 수행하는 코드를 직접 작성해보고 실행해보도록 하자. 이 과정을 수행하면서 우리는 호스트 장치에서 디바이스 장치에서의 연산을 어떻게 실행하고 결과를 받아볼 수 있는지 그 매커니즘에 대해서도 이해해보도록 하자.1. Kernel 작성하기디바이스 장치에서 연산을 실행하기 위해서 어떤 연산을 실행할지 가장 먼..
[CUDA] GPU를 구성하는 여러가지 단위: Kernel, Grid, Block, Thread, Warp, 그리고 첫 프로그램 Hello.cu! 이번 포스팅에서는 GPU를 구성하는 여러가지 단위에 대해서 이론적으로 이해해보고 실제로 이 단위를 코드 레벨에서 확인해보는 첫 프로그램인 Hello.cu 소스코드도 작성해보고 실행해보려 한다. 참고로 해당 포스팅은 AI와 NVIDIA에서 공식적으로 게시하는 문서인 CUDA Programming Guide 문헌을 기반으로 만들어졌음을 알립니다. 개인적으로 최대한 엄밀하게 검증을 거쳤으며 혹여나 잘못된 내용이 있다라고 판단되면 적극 피드백 부탁드립니다. 1. GPU 장치에서 실행되는 함수: Kernel우리에게 익숙하고 그동안 잘 이용해왔던 컴퓨터에서 IDE를 켜고 아무 프로그래밍 언어 하나를 선택해서 Hello World! 라는 문자열을 출력시키는 함수를 만들고 실행한다고 해보자. 이 때, Hello Wor..
[CUDA] CLion + Lightening.ai 로 무료 CUDA 프로그래밍 환경 세팅 이전에 인프런의 널널한 개발자 강사님 강의로 C++ 기초를 입문했다. 이전에 C 강의도 듣긴했었는데 C언어에서 객체지향 패러다임이 추가된 C++인 점, 그리고 ML 플랫폼 엔지니어로서 계속 보편적으로 이용되고 있는 하드웨어인 GPU에 대한 지식을 쌓기 위해서 GPU에서의 로직을 프로그래밍하는 CUDA가 C/C++ 기반인 점을 고려해서 최근부터 CUDA 프로그래밍을 공부하기 시작했다. 앞으로의 포스팅 시리즈에서 C/C++언어에 대한 기초 문법이나 이런 것들을 당연히 알고 있다는 전제하에 진행한다. 사실 언어에 대한 문법 및 사용법들은 AI가 훨씬 잘 대답해주기 때문에 여기서는 길게 설명하지 않는다. 우리가 앞으로 집중할 내용은 CUDA 프로그래밍을 수행하면서 GPU 하드웨어가 어떤 구조로 구성되어 있고..
[Milvus] 자료구조와 SQL 인터페이스의 종류 🔊 해당 포스팅은 Milvus 공식 문서를 기반으로, 그리고 본인의 Milvus 구축 및 운영 경험을 바탕으로 개인적인 기록 및 영구적인 기억을 위해 작성되었습니다. 해당 자료에 등장하는 자료들은 모두 Milvus 공식 문서 또는 본인이 직접 재구성한 자료임을 밝힙니다. 2024년 9월, 새로운 회사로의 이직하면서 사내에 존재하지 않았던 ML 인프라를 밑단부터 구축해나가기 시작했다. 그 과정에서 여러가지 기술과 툴들을 도입하고 적용해왔다. 약 1년이라는 시간이 지난 후, 그동안의 시간을 되돌아보았을 때 가장 구축하고 운영하기 힘들었던 것이 무엇인지 묻는다면 오픈소스 기반의 벡터 DB인 Milvus를 k8s 환경에 구축하고 운영했던 일이라고 말하고 싶다. Milvus를 구축하고 운영하면서 가장 답답했던 ..
[CS] 나만의 컴파일러를 만들어보자! (1): 컴파일러와 가상머신 🔊 해당 포스팅은 밑바닥부터 만드는 인터프리터 in go 책을 읽고 개인적인 정리 목적 하에 작성된 글입니다. 본 포스팅에 사용된 자료는 모두 본인이 직접 재구성하여 작성하였음을 알립니다. 이전 포스팅까지는 밑바닥부터 만드는 인터프리터 책을 읽고 정리한 내용들을 포스팅해왔었다. 마지막에 인터프리터를 디벨롭하는 내용에 대해서는 마저 기록하지 못했지만 기본적인 인터프리터 내용은 모두 학습했다고 생각해서 두번째 시리즈 책인 컴파일러 관련 책을 공부해보고 내용을 기록해보려고 한다. 그 중 가장 첫번째 챕터로, 컴파일러와 가상머신이라는 개념에 대해서 이해해볼 필요가 있다.1. 컴파일러는 추상적인 개념일 뿐!만약 나에게 컴파일러는 무엇이고 내부 구조는 어떻게 동작하는지 말해보라 한다거나 컴파일러를 간단하게 구현해..
[LinkedList] 단일 연결 리스트의 마지막에서 m번째 원소 이번 포스팅은 "프로그래밍 면접, 이렇게 준비한다" 라는 책 서적에 실린 면접 문제 중 '단일 연결 리스트의 마지막에서 m번째 원소' 라는 문제를 풀어볼 예정이다. 문제는 다음과 같다. Head 포인터만 갖는 단일 연결 리스트가 주어졌을 때 리스트의 맨 뒤에서 m번째 원소를 찾아내는 알고리즘을 만들어라. 이 때 시간, 공간 효율을 모두 고려해야 한다. 오류 조건의 처리에 주의하여 알고리즘을 구현해라. 여기에서 '맨 뒤에서 m번째 원소'는 m = 0일 때 리스트의 마지막 원소를 반환하는 식으로 생각한다. Step01. 아이데이션가장 처음에 떠올린 아이디어는 연결 리스트를 한 번 순회하면서 원소들을 별도의 자료구조에 저장 해두고 리스트 끝에 도달했을 때 연결 리스트의 총 길이인 N을 얻게 된다. 그리고 저장..
[LinkedList] 연결 리스트의 꼬리 포인터 이번 포스팅은 "프로그래밍 면접, 이렇게 준비한다" 라는 책 서적에 실린 면접 문제 중 '연결 리스트의 꼬리 포인터' 라는 문제를 풀어볼 예정이다. 문제는 다음과 같다. 정수를 저장하기 위한 어떤 단일 연결 리스트의 첫 번째와 마지막 원소를 가리키는 head와 tail 이라는 전역 포인터가 있다. 다음과 같은 함수 원형에 대해서 함수를 구현해라.(아래 인터페이스는 C 함수 기준이지만 우리는 Golang으로 구현 예정)- bool delete(Element *elem);- bool insertAfter(Element *elem, int data);delete 함수의 인자는 삭제할 원소다. insertAfter 함수의 두 인자는 각각 새로 추가되는 원소의 바로 앞인 이전 원소에 대한 포인터와 새 원소의 데이..
[LinkedList+Array] Golang으로 구현하는 Stack 이번 포스팅에서는 Golang으로 단일 연결 리스트 자료구조를 기반으로 Stack 자료구조를 구현하는 방법에 대해 알아보도록 하자. 해당 포스팅은 "프로그래밍 면접, 이렇게 준비한다" 라는 책 서적에 실린 면접 문제를 기반으로 한다. 문제는 다음과 같다. 스택 자료구조에 대해 논하라. 연결 리스트와 동적 배열을 써서 스택을 구현하고, Push, Pop 이라는 메소드를 구현해서 스택 인터페이스를 설계해라. 먼저 연결 리스트를 활용해서 구현해보도록 하자.1. 단일 연결 리스트를 활용한 StackStep01. 아이데이션가장 먼저 스택 자료구조에 대해 이해해야 한다. 스택은 FILO(First In, Last Out)을 기반으로 하는 자료구조이다. 즉, 가장 첫번째 넣은 원소는 가장 마지막에 나오고, 가장 마지..
[LinkedList] Golang으로 구현하는 단일 연결 리스트 이번 포스팅에서는 Golang으로 구현하는 단일 연결 리스트에 대해 알아보자. 단일 연결 리스트는 아래와 같은 구조로 되어 있는 자료구조를 의미한다. 하나의 원소 안에는 데이터와 해당 원소의 다음 원소를 가리키는 이른바 포인터 또는 레퍼런스가 담겨 있다. 위 그림 상으로 이해해보자. 첫번째 원소에 11 이라는 data를 갖고 있다. 그리고 두번째 원소를 가리키는 포인터에는 200 이라는 숫자가 들어 있다. 이 200이라는 숫자는 2번째 원소의 위치를 의미한다. 이 '원소의 위치'라는 것이 곧 메모리 주소이고 그래서 포인터라고 부르기도 한다. 우리는 위와 같은 단일 연결 리스트 자료구조를 Golang 으로 구현해보려고 한다. 앞으로의 단계를 하나씩 따라가보도록 하자.Step01. 원소(a.k.a 노드) ..
[CS] 나만의 인터프리터를 만들어보자! (3): 평가 🔊 해당 포스팅은 밑바닥부터 만드는 인터프리터 in go 책을 읽고 개인적인 정리 목적 하에 작성된 글입니다. 본 포스팅에 사용된 자료는 모두 본인이 직접 재구성하여 작성하였음을 알립니다. 저번 포스팅까지 해서 우리는 Monkey 라는 우리만의 프로그래밍 언어를 렉싱하는 렉서와 파싱하는 파서 2가지를 모두 Golang 기반으로 만들어보았다. 그리고 우리는 파서의 결과물로 AST 자료구조까지 만드는 것까지 모두 해보았다. 이제는 렉서와 파서의 입력으로 들어간 Monkey 언어 소스코드 문자열이 실제 의미를 갖도록 해주는 평가(Evaluation)를 하는 방법에 대해 배워볼 것이다.1. 인터프리터의 마지막 단계: 평가(Evaluation) 프로세스우리가 처음에 렉서를 만들 때 보았던 그림을 다시 갖고와 보..
[CS] 나만의 인터프리터를 만들어보자! (2): Parser 만들기 - 세번째 🔊 해당 포스팅은 밑바닥부터 만드는 인터프리터 in go 책을 읽고 개인적인 정리 목적 하에 작성된 글입니다. 본 포스팅에 사용된 자료는 모두 본인이 직접 재구성하여 작성하였음을 알립니다. 직전 포스팅에서는 우리만의 파서에 다양한 표현식을 파싱하는 기능을 탑재해보았다. 다만, 마지막에 중위 표현식을 파싱하는 기능을 구현하면서 소스코드를 살펴보는 것만으로 끝냈는데, 이번 포스팅에서는 도식화를 해보면서 소스코드랑 매핑한 후, 구체적으로 우리가 구현한 프랫파서가 어떻게 동작하는지 살펴볼 것이다. 그리고 더 나아가 다른 종류의 표현식도 파싱할 수 있도록 기능을 추가해보자.1. 프랫(Pratt) 파서의 동작 원리가장 마지막으로 구현했던 중위 표현식을 파싱하는 동작을 살펴보면서 프랫 파서의 동작 원리를 이해해보자..
[CS] 나만의 인터프리터를 만들어보자! (2): Parser 만들기 - 두번째 🔊 해당 포스팅은 밑바닥부터 만드는 인터프리터 in go 책을 읽고 개인적인 정리 목적 하에 작성된 글입니다. 본 포스팅에 사용된 자료는 모두 본인이 직접 재구성하여 작성하였음을 알립니다. 이번 포스팅에서는 직전 포스팅까지 해서 만들었던 우리만의 파서에 표현식을 파싱할 수 있는 기능을 탑재해볼 것이다. 코드레벨로 알아보기에 앞서 표현식 파싱이라는 것을 구현할 때 알아두어야할 사전 개념 몇 가지와 고려사항에 대해서 짚고 넘어가보자.1. 표현식 파싱을 하기 전에..직전 포스팅에서 구현했던 let 문, return 문 파싱은 let 또는 return 문 다음에 어떤 토큰들이 등장할지 명확했다. 하지만 표현식 파싱은 let, return 문 파싱처럼 쉽게 구현할만큼은 아니며 꽤 까다로운 작업이다.  가장 먼저..
[CS] 나만의 인터프리터를 만들어보자! (2): Parser 만들기 - 첫번째 🔊 해당 포스팅은 밑바닥부터 만드는 인터프리터 in go 책을 읽고 개인적인 정리 목적 하에 작성된 글입니다. 본 포스팅에 사용된 자료는 모두 본인이 직접 재구성하여 작성하였음을 알립니다. 직전 포스팅에서 우리는 입력된 소스코드 문자열을 토큰화시키는 렉서를 직접 만들고 테스트를 해보았다. 이번 포스팅에서는 이 렉서가 만들어낸 토큰들을 가지고 AST(추상 구문 트리)와 같은 자료구조로 변환을 수행하는 파서(Parser)를 만들어보도록 하자. 해당 챕터는 내용이 길어지기 때문에 몇 개의 포스팅으로 나누어서 게시할 예정이다. 이제 파서를 만들어보는 첫 걸음을 내딛어보자.1. Parser란 무엇일까?파서를 만들어보기 전, 우리는 파서라는 것이 무엇이고 어떤 역할을 하는지 알아야 만들어가면서 그 의미를 제대로 ..
[CS] 나만의 인터프리터를 만들어보자!(1): Lexer 만들기 🔊 해당 포스팅은 밑바닥부터 만드는 인터프리터 in go 책을 읽고 개인적인 정리 목적 하에 작성된 글입니다. 본 포스팅에 사용된 자료는 모두 본인이 직접 재구성하여 작성하였음을 알립니다. 최근에 C언어를 조금씩 접하기 시작하면서 로우 레벨 프로그래밍 언어 공부에 대한 갈증이 많아졌다. 하지만 C언어에 대한 기초를 배우고 난 뒤, 가장 당혹스러웠던 부분은 현재 실무에서 C언어를 자주 접할 일이 없어서 프로젝트 할만한 게 없다는 것이었다. 물론 Python의 구현체 중 하나인 CPython 소스코드를 살펴볼 수 있겠지만, 이것도 단지 '보기만 할 뿐'이지, 뭔가 결과물이 있거나 내 지식으로 체득되는 느낌이 아니었다. 그러던 중, 요즘 실무에서 쿠버네티스 기술과 Go로 작성된 벡터 데이터베이스인 Milvu..
[CS] 여러 가지 문자열 인코딩 방법과 base64 인코딩 🔊 해당 포스팅은 개인적으로 구독하고 있는 널널한 개발자님의 무료 유투브 강의인 문자열 인코딩과 base64 인코딩 영상을 보고 개인적인 목적 하에 작성되는 글입니다. 포스팅에 사용되는 모든 자료는 제가 직접 재구성하였음을 알립니다.최근에 C 언어와 Go 언어를 조금씩 접하기 시작하면서 원툴로 사용해오던 Python 언어에 비해 다르게 느껴지는 점이 무수히 많았다. 그 중에 하나로서 컴퓨터가 문자 또는 문자열을 표현하는 방법인 문자열 인코딩에 대해서 확실히 알아두어야 겠다는 생각이 들었다. 그리고 또 다른 자매품(?)으로 base64 인코딩이 어떻게 동작하는지, 그리고 왜 사용되는지에 대해서도 같이 공부하면 좋겠다 싶었다. 1. 문자 인코딩의 시작: ASCII(아스키) 코드프로그래밍을 해보거나 코딩 테..
[Kubernetes] 쿠버네티스에서의 모니터링(feat. Prometheus) 🔊 해당 포스팅은 시작하세요! 도커/쿠버네티스 서적을 읽고 개인적인 목적 하에 작성되는 글입니다. 포스팅에 사용되는 모든 자료는 제가 직접 재구성하였음을 알립니다. 이번 포스팅에서는 쿠버네티스에서의 모니터링에 대해서 다루어보려고 한다. 직전 포스팅까지는 쿠버네티스에서 어떠한 리소스 오브젝트를 생성하고 적용하는 방법에 대해 주로 배워왔다면 이제는 지금까지 생성해온 리소스들의 상태가 현재 어떤지, 장애가 난 건 아닌지를 모니터링 하는 시스템을 쿠버네티스에서 어떻게 구축할 수 있는지에 대해 배워본다. 사실 쿠버네티스에서 자체적으로 제공하는 모니터링 기능은 없다. 보통은 프로메테우스와 같은 오픈소스 도구들을 조합하거나 Datadog과 같은 유료 솔루션을 도입해서 쿠버네티스에서의 모니터링 시스템을 구축하게 된다..
[Kubernetes] k8s에서의 접근 권한 제어하기: SA와 RBAC 🔊 해당 포스팅은 시작하세요! 도커/쿠버네티스 서적을 읽고 개인적인 목적 하에 작성되는 글입니다. 포스팅에 사용되는 모든 자료는 제가 직접 재구성하였음을 알립니다. 일반적으로 쿠버네티스를 사용하는 환경은 한 명의 개발자가 운영하고 사용하는 경우는 거의 없다. 대부분 여러 명의 DevOps 개발자 또는 여러 명의 백엔드 개발자, MLOps 개발자 등 인프라를 들여다보는 개발자들이 함께 사용한다. 하지만 이 모든 개발자들이 동일한 범위의 권한으로 k8s 클러스터를 제어하지는 않는다. 운영체제가 유저 별로 디렉토리 또는 파일에 접근 권한을 다르게 부여하여 관리하는 것처럼 쿠버네티스에서도 유저 또는 애플리케이션 별로 쿠버네티스에 접근 권한을 제어할 수가 있다. 이번 포스팅에서는 쿠버네티스에서 RBAC(Role..
[CS] SSL/TLS 인증서는 어떻게 등장했을까? 🔊 해당 포스팅은 인프런 강의 널널한개발자님의 외워서 끝내는 SSL과 최소한의 암호기술 내용을 공부하면서 배운 내용을 저만의 방식으로 재정리하고자 하는 목적 하에 작성되는 포스팅입니다. 아래 포스팅에서 사용되는 모든 자료는 제가 직접 재구성했음을 알립니다. 이번 포스팅에서는 컴퓨터 공학에서 주로 사용되는 기초적인 암호기술과 관련해서 소개하려고 한다. 현재 웹 통신에서 가장 자주 사용되는 SSL/TLS 인증서가 등장하기 이전의 전통적인 암호기술은 어떤 방식을 채택했는지, 그리고 어떤 문제점이 있어 지금의 SSL/TLS 인증서까지 오게 되었는지 시간의 흐름 순으로 살펴보도록 하자. 그에 앞서서 기초적인 암호기술 관련된 몇 가지 개념들에 대해서 배워보도록 하자.1. Checksum과 Hash체크섬(Check..
[Kubernetes] 파드를 사용하는 또 다른 오브젝트들: Jobs, DaemonSets, StatefulSets 🔊 해당 포스팅은 시작하세요! 도커/쿠버네티스 서적을 읽고 개인적인 목적 하에 작성되는 글입니다. 포스팅에 사용되는 모든 자료는 제가 직접 재구성하였음을 알립니다. 이번 포스팅에서는 파드를 사용하는 또 다른 상위 리소스 오브젝트들로 Jobs, DaemonSet, StatefulSet에 대해서 알아보도록 하자. 지금까지 살펴본 ReplicaSet, Deployment 와 같은 리소스 오브젝트들도 배웠었는데, 이것들도 파드를 사용하는 상위 리소스 오브젝트들이라고 할 수 있다. 하지만 파드를 사용하는 리소스 오브젝트들로서 Jobs, DaemonSet, StatefulSet은 Replicaset, Deployment 와는 약간 다른 목적으로 사용하곤 한다. 하나씩 살펴보도록 하자.1. 특정 동작을 수행하고 종..
[Kubernetes] CRD, 커스텀 리소스, 그리고 컨트롤러 🔊 해당 포스팅은 시작하세요! 도커/쿠버네티스 서적을 읽고 개인적인 목적 하에 작성되는 글입니다. 포스팅에 사용되는 모든 자료는 제가 직접 재구성하였음을 알립니다. 이번 포스팅에서는 쿠버네티스에서 커스텀 리소스, CRD, 그리고 컨트롤러에 대해 알아본다. 직전 포스팅까지 우리는 모두 쿠버네티스에서 자체적으로 제공하는 리소스 오브젝트를 생성해왔다. 파드, 레플리카셋, 디플로이먼트, HPA, 스토리지 클래스, PV, PVC 등등 이런 리소스 오브젝트들은 쿠버네티스를 설치하기만 하면 기본적으로 내장되어 있어 사용할 수 있는 오브젝트들이다.  하지만 이렇게 기본적으로 쿠버네티스에서 제공하는 리소스 오브젝트 말고도 우리가 직접 새로운 리소스의 종류를 만들어서 쿠버네티스에서도 사용할 수 있다. 이렇게 직접 만든 ..