| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |
- directx
- 운영체제
- 병행성
- 멀티프로세서
- 컨디션 변수
- 그리디 알고리즘
- 렌더링 파이프라인
- Direct12
- 멀티쓰레드
- 디자인패턴
- I/O장치
- 병행성 관련 오류
- 동적계획법
- codility
- 파일시스템 구현
- 쓰레드
- 타입 객체
- 영속성
- 락
- 백준
- 알고리즘
- DirectX12
- 다이나믹 프로그래밍
- 자료구조
- 프로그래머스
- 다이나믹프로그래밍
- 그리디알고리즘
- 스케줄링
- DirectX 12
- OS
- Today
- Total
목록분류 전체보기 (499)
기록공간
정렬 조건을 정하여 정렬하는 문제이다. 위 설명처럼 순열을 모두 구해서 내림차순으로 정렬하는 방법을 생각해 볼 수 있다. 값은 정확하게 나오지만 순열의 개수는 (numbers의 원소의 개수)! (팩토리얼)이기 때문에 원소의 갯수가 많을수록 기하급수적으로 많아진다. 결국 시간 초과가 되므로 이 방법은 쓸 수 없다. (STL에서 제공하는 next_permutation을 사용하면 순열을 쉽게 구할 수 있으므로 한번 시도해보는 것도 나쁘지 않다) 정렬을 내림차순으로 하더라도 [6, 10, 2] 같은 경우 [10, 6, 2]로 1062가 되므로 가장 큰 수를 만족하지 못한다. 하지만 원소들을 string으로 바꾸고 서로의 조합을 통해 비교해서 정렬하면 어떨까? 예를 들어 [6, 10, 2]가 있다면 이를 stri..
세마포어는 정수 값을 갖는 객체로서 두 개의 루틴으로 조작할 수 있다. 이 두 개의 루틴은 각각 sem_wait()와 sem_post()이다. 세마포어는 초기값에 의해 동작이 결정되기 때문에, 사용하기 전 "제일 먼저" 값을 초기화해야 한다. class semaphore { int value; semaphore() {value = 1;} }; 세마포어 객체 정수 값을 1로 초기화 한다. 이제 세마포어 내에 있는 sem_wait()와 sem_post() 메서드를 살펴보도록 하겠다. 이 둘은 원자적으로 실행된다. 레이스 컨디션 (쓰레드 간의 공유하는 값을 서로 쓰려고 하는 경쟁상태)이 발생할 수 있다는 사실은 걱정하지 말자. 그것은 곧 락과 컨디션 변수를 사용하게 될 것이다. * sem_wait() int ..
지금까지 락의 개념을 학습하고 하드웨어와 운영체제의 적절한 지원을 통해 제대로 된 락을 만드는 법을 살펴보았다. 불행히도 "락"만으로는 병렬 프로그램을 제대로 작성할 수 없다. 쓰레드가 계속 진행하기 전에 어떤 조건(Condition)이 참인지를 검사해야 하는 경우가 많이 있다. 예를 들어 부모 쓰레드가 작업을 시작하기 전에 자식 쓰레드가 작업을 끝냈는지를 검사하기를 원할 수 있다.(보통 join() 연산이라고 불린다) 이러한 대기문은 어떻게 구현해야 할까? void child() { std::cout
상수 버퍼 상수 버퍼의 생성 상수 버퍼는 쉐이더 프로그램에서 참조하는 자료를 담는 GPU 자원(ID3D12Resource)의 예이다. 앞에서 말했듯이 텍스처나 기타 버퍼 자원 역시 쉐이더 프로그램에서 참조할 수 있다. 이전에 봤던 정점 쉐이더 코드에 이런 코드가 있었다. cbuffer cbPerObject : register(b0) { float4x4 gWorldViewProj; }; 이 코드는 cbPerObject라는 cbuffer 객체(상수 버퍼)를 참조한다. 이 예에서 상수 버퍼는 gWorldViewProj라는 4 x 4 행렬 하나만 저장한다. 이 행렬은 한 점을 Local space에서 동차 절단 공간으로 변환하기 위해, World 행렬, View 행렬, Projection 행렬을 결합한 것이다...
인덱스와 인덱스 버퍼 정점들과 마찬가지로, GPU가 인덱스의 배열에 접근할 수 있으려면 인덱스들을 버퍼 GPU자원(ID3D12Resource)에 넣어 두어야 한다. 인덱스들을 담는 버퍼를 인덱스 버퍼라고 부른다. d3dUtil:: CreateDefaultBuffer 함수(이전 장에서 설명했었음)는 void*를 통해 자료를 처리하므로, 인덱스 버퍼뿐만 아니라 모든 기본 버퍼를 생성할 수 있다. 인덱스 버퍼를 파이프라인에 묶으려면 인덱스 버퍼 자원을 서술하는 인덱스 버퍼 뷰를 만들어야 한다. 정점 버퍼 뷰처럼 인덱스 버퍼 뷰에도 서술자 힙이 필요하지 않다. 인덱스 버퍼 뷰를 대표하는 형식은 구조체 D3D12_INDEX_BUFFER_VIEW이다. typedef struct D3D12_INDEX_BUFFER_V..
흔하게 사용되는 자료 구조에서 락을 사용하는 방법을 살펴보도록 하겠다. 자료 구조에 락을 추가하여 쓰레드가 사용할 수 있도록 만들면 그 구조는 쓰레드 사용에 안전(thread safe)하다고 할 수 있다. 물론 락인 어떤 방식으로 추가되었느냐에 따라 자료 구조의 정확성과 성능을 좌우할 것이다. 병렬 카운터 카운터는 가장 간단한 자료 구조 중 하나이다. 보편적으로 사용되는 구조이면서 인터페이스가 간단하다. 간단하지만 확장성이 없음 동기화되지 않은 카운터는 몇 줄 안되는 코드로 작성할 수 있는 평범한 자료 구조이다. 다음은 락이 없는 카운터의 코드이다. class counter_t { int value; public: counter_t() {value = 0:} void increment() {value++..
이번 장에서는 그리는 과정에 필요한 Direct3D API의 여러 인터페이스와 메서드를 중점적으로 살펴본다. (코드는 https://github.com/d3dcoder/d3d12book에서 받을 수 있다. (chapter 6)) 정점과 입력 배치 Direct3D는 정점의 위치 이외의 추가적인 자료를 부여할 수 있다. 원하는 자료를 가진 정점 형식을 만들려면 우선 그러한 자료(벡터 형식)를 담을 구조체를 정의해야 한다. 다음은 서로 다른 두 가지 정점 형식의 예이다. 하나는 위치의 색상으로 구성되고 또 하나는 위치, 법선, 그리고 두 개의 텍스처 좌표로 구성된다. struct Vertex1 { XMFLOAT3 Pos; XMFLOAT3 Color; }; struct Vertex2 { XMFLOAT3 Pos;..
Fetch-And-Add 마지막 하드웨어 기반의 기법은 Fetch-And-Add 명령어로 원자적으로 특정 주소의 예전 값을 반환하면서 값을 증가시킨다. C, C++ 코드로 표현하면 다음과 같다. // C int FetchAndAdd(int *ptr) { int old = *ptr; *ptr = old + 1; return old; } // C++ #include int FetchAndAdd(std::atomic_int &ptr) { return ptr++; } C++ 코드를 보면 atomic_int이 보일 것이다. 이건 무엇일까? C++11부터 지원하는 Atomic 자료구조이다. 이것은 기본 자료 구조의 일부를 원자적으로 구현해놓은 것이다.(char, int, short, bool) Atomic 자료구조..