계산 GPU

CUDA(Compute Unified Device Architecture) 기술은 GPGPU(Arbitrary Computing on Video Card) 기술을 지원하는 NVIDIA GPU를 사용하여 컴퓨팅을 가능하게 하는 소프트웨어 및 하드웨어 아키텍처입니다. CUDA 아키텍처는 8세대 NVIDIA 칩인 G80의 출시와 함께 시장에 처음 등장했으며 GeForce, ION, Quadro 및 Tesla 가속기 제품군에 사용되는 모든 후속 그래픽 칩 시리즈에 사용됩니다.

CUDA SDK를 통해 프로그래머는 C 프로그래밍 언어의 특별 단순화된 방언으로 NVIDIA GPU에서 실행될 수 있고 C 프로그램 텍스트에 특수 기능을 포함할 수 있는 알고리즘을 구현할 수 있습니다. CUDA는 개발자에게 자신의 재량에 따라 그래픽 가속기의 명령어 세트에 대한 액세스를 구성하고 메모리를 관리하고 이에 대한 복잡한 병렬 컴퓨팅을 구성할 수 있는 기회를 제공합니다.

이야기

2003년 Intel과 AMD는 강력한 프로세서. 수년에 걸쳐, 특히 Intel Pentium 4가 출시된 후 이 경쟁의 결과로 클럭 속도가 크게 향상되었습니다.

클럭 주파수가 증가한 후(2001년에서 2003년 사이에 펜티엄 4 클럭 주파수는 1.5GHz에서 3GHz로 두 배 증가) 사용자는 제조업체가 시장에 출시한 1/10GHz에 만족해야 했습니다(2003년에서 2005년, 클럭 주파수가 3에서 3.8GHz로 증가함).

Prescott과 같이 높은 클럭 속도에 최적화된 아키텍처도 프로덕션 단계에서뿐만 아니라 어려움을 겪기 시작했습니다. 칩 제조업체는 물리 법칙을 극복하는 데 어려움을 겪었습니다. 일부 분석가들은 무어의 법칙이 더 이상 작동하지 않을 것이라고 예측했습니다. 그러나 그런 일은 일어나지 않았습니다. 법의 본래 의미는 잘못 표현되는 경우가 많은데, 이는 실리콘 코어 표면에 있는 트랜지스터의 수를 의미합니다. 오랫동안 CPU의 트랜지스터 수가 증가하면 그에 따라 성능이 향상되어 의미가 왜곡되었습니다. 그러나 상황은 더 복잡해졌습니다. CPU 아키텍처의 설계자들은 이득 감소의 법칙에 접근했습니다. 원하는 성능 향상을 위해 추가해야 하는 트랜지스터의 수가 점점 더 많아져 막다른 골목에 이르렀습니다.

GPU 제조업체가 이 문제에 직면하지 않은 이유는 매우 간단합니다. CPU는 다른 데이터(정수 및 부동 소수점 숫자 모두)를 처리하고 메모리에 대한 임의 액세스 등을 수행하는 명령 스트림에서 최상의 성능을 얻도록 설계되었습니다. d. 지금까지 개발자들은 가능한 한 많은 명령어를 병렬로 실행하기 위해 더 큰 명령어 병렬성을 제공하려고 노력해 왔습니다. 예를 들어, 특정 조건에서 클록당 두 개의 명령을 실행할 수 있을 때 펜티엄에서 슈퍼스칼라 실행이 나타났습니다. Pentium Pro는 명령의 비순차적 실행을 수신하여 컴퓨팅 장치의 성능을 최적화할 수 있었습니다. 문제는 명령의 순차 스트림을 병렬로 실행하는 데는 명백한 한계가 있으므로 대부분의 시간이 여전히 유휴 상태일 것이기 때문에 맹목적으로 컴퓨팅 장치의 수를 늘리는 것이 이득이 되지 않는다는 것입니다.

GPU 작동은 비교적 간단합니다. 한 면에 폴리곤 그룹을 가져오고 다른 면에 픽셀 그룹을 생성하는 것으로 구성됩니다. 다각형과 픽셀은 서로 독립적이므로 병렬로 처리할 수 있습니다. 따라서 GPU에서는 CPU와 달리 실제로 사용되는 컴퓨팅 장치에 크리스탈의 많은 부분을 할당할 수 있습니다.

GPU는 이것뿐만 아니라 CPU와 다릅니다. GPU의 메모리 액세스는 매우 결합되어 있습니다. 텍셀을 읽으면 몇 사이클 후에 이웃 텍셀이 읽힙니다. 픽셀이 기록될 때 인접 픽셀은 몇 사이클 후에 기록됩니다. 메모리를 지능적으로 구성하면 이론적인 대역폭에 가까운 성능을 얻을 수 있습니다. 이는 GPU의 역할이 텍스처링 작업의 속도를 높이는 것이기 때문에 CPU와 달리 GPU는 큰 캐시를 필요로 하지 않는다는 것을 의미합니다. 이중선형 및 삼선형 필터에 사용되는 몇 개의 텍셀을 포함하는 몇 킬로바이트만 있으면 됩니다.

GPU에서의 첫 번째 계산

이러한 응용 프로그램에 대한 최초의 시도는 래스터화 및 Z-버퍼링과 같은 일부 하드웨어 기능의 사용으로 제한되었습니다. 그러나 현재 세기에 셰이더의 출현으로 행렬 계산 속도가 빨라지기 시작했습니다. 2003년에는 GPU 컴퓨팅을 위해 SIGGRAPH에 별도의 섹션이 할당되었으며, 이를 GPGPU(범용 GPU 컴퓨팅 - 범용 GPU 컴퓨팅)라고 불렀습니다.

가장 잘 알려진 BrookGPU는 GPU에서 비그래픽 계산을 수행하도록 설계된 Brook 스트림 프로그래밍 언어 컴파일러입니다. 등장하기 전에 계산을 위해 비디오 칩의 기능을 사용하는 개발자는 Direct3D 또는 OpenGL의 두 가지 공통 API 중 하나를 선택했습니다. 3D 그래픽은 병렬 프로그래머가 알 필요가 없는 셰이더와 텍스처를 사용하고 스레드와 코어를 사용하기 때문에 GPU 사용이 심각하게 제한되었습니다. Brook은 그들의 작업을 더 쉽게 만드는 데 도움을 줄 수 있었습니다. 스탠포드 대학에서 개발된 C 언어에 대한 이러한 스트리밍 확장은 프로그래머에게 3D API를 숨기고 비디오 칩을 병렬 보조 프로세서로 표시했습니다. 컴파일러는 C++ 코드 및 확장자가 있는 .br 파일을 구문 분석하여 DirectX, OpenGL 또는 x86 지원 라이브러리에 연결된 코드를 생성합니다.

Brook의 등장은 NVIDIA와 ATI의 관심을 불러일으켰고 비디오 칩을 기반으로 하는 병렬 컴퓨터라는 완전히 새로운 영역을 더욱 열었습니다.

또한 Brook 프로젝트의 일부 연구원들은 하드웨어-소프트웨어 병렬 컴퓨팅 전략을 도입하기 위해 NVIDIA 개발 팀으로 이동하여 새로운 시장 점유율을 개척했습니다. 그리고 이 NVIDIA 이니셔티브의 주요 장점은 개발자가 GPU의 모든 기능을 가장 작은 세부 사항까지 완벽하게 알고 있으며 그래픽 API를 사용할 필요가 없으며 드라이버를 사용하여 직접 하드웨어로 작업할 수 있다는 것입니다. 이 팀의 노력의 결과가 NVIDIA CUDA입니다.

GPU에서 병렬 계산의 적용 영역

컴퓨팅이 GPU로 전달되면 많은 작업에서 고속 범용 프로세서에 비해 5~30배의 가속이 달성됩니다. SSE 블록을 사용하는 계산에는 적합하지 않지만 GPU에는 매우 편리한 코드에서 가장 큰 숫자(100배 속도 향상 및 그 이상!)가 달성됩니다.

다음은 GPU의 합성 코드와 CPU의 SSE 벡터화 코드(NVIDIA에 따름)의 속도 향상에 대한 몇 가지 예일 뿐입니다.

형광 현미경: 12x.

분자 역학(비결합력 계산): 8-16x;

정전기(직접 및 다중 레벨 쿨롱 합산): 40-120x 및 7x.

NVIDIA가 모든 프레젠테이션에 표시하는 표로 CPU와 관련된 GPU의 속도를 보여줍니다.

GPU 컴퓨팅이 사용되는 주요 응용 프로그램 목록: 이미지 및 신호 분석 및 처리, 물리학 시뮬레이션, 계산 수학, 컴퓨터 생물학, 재무 계산, 데이터베이스, 기체 및 액체 역학, 암호학, 적응 방사선 요법, 천문학, 음향 처리, 생물 정보학 , 생물학적 시뮬레이션, 컴퓨터 비전, 데이터 마이닝, 디지털 영화 및 텔레비전, 전자기 시뮬레이션, 지리 정보 시스템, 군사 응용 프로그램, 광산 계획, 분자 역학, 자기 공명 영상(MRI), 신경망, 해양 연구, 입자 물리학, 단백질 접힘 시뮬레이션, 양자 화학, 광선 추적, 이미징, 레이더, 저수지 시뮬레이션, 인공 지능, 위성 데이터 분석, 지진 탐사, 수술, 초음파, 화상 회의.

CUDA의 장점과 한계

프로그래머의 관점에서 그래픽 파이프라인은 일련의 처리 단계입니다. 기하학 블록은 삼각형을 생성하고 래스터화 블록은 모니터에 표시되는 픽셀을 생성합니다. 기존의 GPGPU 프로그래밍 모델은 다음과 같습니다.

이러한 모델의 프레임워크 내에서 GPU로 계산을 전송하려면 특별한 접근 방식이 필요합니다. 두 벡터를 요소별로 추가하는 경우에도 화면이나 오프스크린 버퍼에 모양을 그려야 합니다. 그림은 래스터화되고 각 픽셀의 색상은 주어진 프로그램(픽셀 셰이더)에 따라 계산됩니다. 프로그램은 각 픽셀의 텍스처에서 입력 데이터를 읽고 더하고 출력 버퍼에 씁니다. 그리고 이 모든 연산은 기존의 프로그래밍 언어에서 단일 연산자로 작성된 작업에 필요합니다!

따라서 범용 컴퓨팅에 GPGPU를 사용하는 것은 개발자가 학습하기에 너무 복잡하다는 형태의 제한이 있습니다. 픽셀 셰이더는 좌표에 대한 픽셀의 최종 색상 의존성에 대한 공식일 뿐이고 픽셀 셰이더 언어는 C와 같은 구문으로 이러한 공식을 작성하기 위한 언어이기 때문에 다른 제한 사항이 충분합니다. 초기 GPGPU 방법은 GPU의 성능을 활용하는 영리한 속임수이지만 편리함은 없습니다. 거기에 있는 데이터는 이미지(텍스처)로 표현되고 알고리즘은 래스터화 프로세스로 표현됩니다. 그것은 기록되어야 하며 매우 구체적인 메모리 및 실행 모델입니다.

NVIDIA의 GPU 컴퓨팅을 위한 NVIDIA의 하드웨어 및 소프트웨어 아키텍처는 표준 구문, 포인터 및 비디오 칩의 컴퓨팅 리소스에 액세스하기 위한 최소한의 확장이 필요한 실제 C로 GPU용 프로그램을 작성할 수 있다는 점에서 이전 GPGPU 모델과 다릅니다. CUDA는 그래픽 API에 의존하지 않으며 범용 컴퓨팅을 위해 특별히 설계된 몇 가지 기능을 가지고 있습니다.

GPGPU 컴퓨팅에 대한 기존 접근 방식에 비해 CUDA의 장점

CUDA는 멀티프로세서당 16KB의 공유 메모리에 대한 액세스를 제공하며, 이는 텍스처 가져오기보다 더 높은 대역폭으로 캐시를 구성하는 데 사용할 수 있습니다.

시스템과 비디오 메모리 간의 보다 효율적인 데이터 전송;

중복성과 오버헤드가 있는 그래픽 API가 필요하지 않습니다.

선형 메모리 주소 지정, 수집 및 분산, 임의 주소에 쓰는 기능

정수 및 비트 연산에 대한 하드웨어 지원.

CUDA의 주요 제한 사항:

실행 가능한 함수에 대한 재귀 지원이 부족합니다.

최소 블록 너비는 32 스레드입니다.

NVIDIA 소유의 폐쇄형 CUDA 아키텍처.

이전 GPGPU 방법을 사용한 프로그래밍의 약점은 이러한 방법이 이전의 비통합 아키텍처에서 정점 셰이더 실행 단위를 사용하지 않고, 데이터가 텍스처에 저장되고 오프스크린 버퍼로 출력되며, 다중 패스 알고리즘이 픽셀 셰이더 단위를 사용한다는 것입니다. GPGPU 제한 사항에는 하드웨어 기능의 불충분한 사용, 메모리 대역폭 제한, 분산 작업 없음(수집만), 그래픽 API의 필수 사용이 포함됩니다.

이전 GPGPU 방법에 비해 CUDA의 주요 이점은 이 아키텍처가 다음과 같이 설계되었다는 사실에서 비롯됩니다. 효과적인 사용그래픽 파이프라인 개념에 편리한 형태로 알고리즘을 전송할 필요 없이 GPU에서 비그래픽 컴퓨팅을 사용하고 C 프로그래밍 언어를 사용합니다. 쿠다 제안 새로운 방법그래픽 API를 사용하지 않고 임의의 메모리 액세스(분산 또는 수집)를 제공하는 GPU 컴퓨팅. 이러한 아키텍처는 GPGPU의 단점이 없고 모든 실행 단위를 사용하며 정수 수학 및 비트 시프트 연산을 통해 기능을 확장합니다.

CUDA는 공유 메모리와 같은 그래픽 API에서 사용할 수 없는 일부 하드웨어 기능을 엽니다. 이것은 스레드 블록이 액세스할 수 있는 소량의 메모리(멀티프로세서당 16킬로바이트)입니다. 가장 자주 액세스하는 데이터를 캐시하고 더 많은 정보를 제공할 수 있습니다. 고속, 이 작업에 텍스처 가져오기를 사용하는 것과 비교됩니다. 이는 차례로 많은 응용 프로그램에서 병렬 알고리즘의 처리량 민감도를 줄입니다. 예를 들어 선형 대수, 고속 푸리에 변환 및 이미지 처리 필터에 유용합니다.

CUDA 및 메모리 액세스에서 더 편리합니다. 프로그램 코드그래픽 API에서 사전 정의된 영역에서 32개의 단정밀도 부동 소수점 값(8개의 렌더링 대상에서 동시에 RGBA 값)의 형태로 데이터를 출력하고 CUDA는 분산 기록을 지원합니다 - 모든 주소에서 레코드의 무제한 . 이러한 장점으로 인해 그래픽 API 기반의 GPGPU 메서드를 사용하여 효율적으로 구현할 수 없는 일부 알고리즘을 GPU에서 실행할 수 있습니다.

또한 그래픽 API는 데이터를 텍스처에 저장해야 하므로 사전에 큰 배열을 텍스처로 패킹해야 하므로 알고리즘이 복잡해지고 특수 주소 지정을 사용해야 합니다. 그리고 CUDA를 사용하면 모든 주소에서 데이터를 읽을 수 있습니다. CUDA의 또 다른 장점은 CPU와 GPU 간의 최적화된 통신입니다. 그리고 저수준(예: 다른 프로그래밍 언어를 작성할 때)에 액세스하려는 개발자를 위해 CUDA는 저수준 어셈블리 언어 프로그래밍의 가능성을 제공합니다.

CUDA의 단점

CUDA의 몇 가지 단점 중 하나는 휴대성이 좋지 않다는 것입니다. 이 아키텍처는 이 회사의 비디오 칩에서만 작동하며 모든 칩에서는 작동하지 않지만 GeForce 8 및 9 시리즈와 해당 Quadro, ION 및 Tesla부터 시작합니다. NVIDIA는 9천만 개의 CUDA 호환 비디오 칩을 제공합니다.

CUDA의 대안

쓰기 프레임워크 컴퓨터 프로그램다양한 그래픽 및 중앙 프로세서의 병렬 컴퓨팅과 관련됩니다. OpenCL 프레임워크에는 C99 표준을 기반으로 하는 프로그래밍 언어와 API(응용 프로그래밍 인터페이스)가 포함됩니다. OpenCL은 명령 수준 및 데이터 수준 병렬 처리를 제공하며 GPGPU 기술의 구현입니다. OpenCL은 완전히 공개된 표준이며 사용에 대한 라이선스 비용이 없습니다.

OpenCL의 목표는 GPU의 성능을 활용하여 3D 컴퓨터 그래픽 및 사운드에 대한 개방형 산업 표준인 OpenGL 및 OpenAL을 보완하는 것입니다. OpenCL은 Apple, AMD, Intel, nVidia, Sun Microsystems, Sony Computer Entertainment 등을 포함한 많은 주요 회사를 포함하는 비영리 컨소시엄인 Khronos Group에서 개발 및 유지 관리합니다.

CAL/IL(컴퓨팅 추상화 계층/중급 언어)

ATI Stream Technology는 하드웨어 및 소프트웨어 기술, CPU와 함께 AMD GPU를 사용하여 많은 응용 프로그램(그래픽뿐만 아니라)을 가속화할 수 있습니다.

ATI Stream의 응용 분야는 다음과 같은 컴퓨팅 리소스를 요구하는 응용 프로그램입니다. 재무 분석또는 지진 데이터 처리. 스트림 프로세서를 사용하면 동일한 문제를 CPU.

NVIDIA는 ATI Stream 기술을 매우 강력한 경쟁자로 간주하지 않습니다. CUDA와 Stream은 개발 수준이 다른 두 가지 다른 기술입니다. ATI 제품을 위한 프로그래밍은 훨씬 더 어렵습니다. 해당 언어는 어셈블러와 비슷합니다. 반면에 CUDA C는 훨씬 더 높은 수준의 언어입니다. 그것에 쓰기가 더 편리하고 쉽습니다. 대규모 개발 회사의 경우 이는 매우 중요합니다. 성능에 대해 이야기하면 ATI 제품의 최고 가치가 NVIDIA 솔루션보다 높다는 것을 알 수 있습니다. 그러나 다시 말하지만, 모든 것은 이 힘을 얻는 방법에 달려 있습니다.

DirectX11(다이렉트컴퓨팅)

실행 중인 IBM PC 호환 컴퓨터에서 실행되도록 설계된 Microsoft의 API 세트인 DirectX의 일부인 응용 프로그래밍 인터페이스 운영체제마이크로소프트 윈도우 제품군. DirectCompute는 GPGPU 개념의 구현인 GPU에서 범용 계산을 수행하도록 설계되었습니다. DirectCompute는 원래 DirectX 11의 일부로 게시되었지만 나중에 DirectX 10 및 DirectX 10.1에서도 사용할 수 있게 되었습니다.

러시아 과학계의 NVDIA CUDA.

2009년 12월 현재, 프로그래밍 모델 CUDA는 전 세계 269개 대학에서 가르치고 있습니다. 러시아에서는 CUDA에 대한 교육 과정이 모스크바, 상트페테르부르크, 카잔, 노보시비르스크 및 페름 주립 대학, 국제 사회 자연 대학 및 Man "Dubna", 핵 연구 공동 연구소, 모스크바 전자 연구소에서 진행됩니다. 기술, Ivanovo State Power Engineering University, BSTU. V. G. Shukhova, MSTU im. Bauman, RKhTU im. Mendeleev, 러시아 연구 센터 "Kurchatov Institute", 러시아 과학 아카데미의 지역 간 슈퍼 컴퓨터 센터, Taganrog Institute of Technology(TTI SFedU).

AMD/ATI Radeon 아키텍처 기능

이것은 생물이 서식지를 개발하는 동안 환경에 대한 적응력을 향상시키기 위해 진화하는 새로운 생물학적 종의 탄생과 유사합니다. 유사하게, 가속화된 삼각형의 래스터화 및 텍스처링으로 시작하는 GPU는 이러한 동일한 삼각형을 색칠하기 위한 셰이더 프로그램을 실행하는 추가 기능을 개발했습니다. 그리고 이러한 기능은 비그래픽 컴퓨팅에서 요구되는 것으로 밝혀졌으며, 어떤 경우에는 기존 솔루션에 비해 상당한 성능 향상을 제공합니다.

우리는 유추를 더 끌어냅니다. 육지에서의 오랜 진화 후에 포유류는 바다로 침투하여 평범한 해양 주민을 밀어냈습니다. 경쟁적인 투쟁에서 포유류는 지구 표면에 나타난 새로운 진보된 능력과 수중 생활에 적응하기 위해 특별히 획득한 능력을 모두 사용했습니다. 마찬가지로 3D 그래픽 아키텍처의 장점을 기반으로 하는 GPU는 비그래픽 작업에 유용한 특수 기능을 점점 더 많이 확보하고 있습니다.

그렇다면 범용 프로그램 분야에서 GPU가 자체 부문을 주장할 수 있는 이유는 무엇일까요? GPU의 마이크로아키텍처는 기존 CPU와 매우 다르게 구축되었으며, 처음부터 몇 가지 장점이 있습니다. 그래픽 작업에는 데이터의 독립적인 병렬 처리가 포함되며 GPU는 기본적으로 다중 스레드입니다. 그러나 이 평행선은 그에게 기쁨일 뿐입니다. 마이크로아키텍처는 실행해야 하는 많은 수의 스레드를 활용하도록 설계되었습니다.

GPU는 Nvidia 용어로 Streaming Multiprocessor라고 하는 수십 개의 프로세서 코어(Nvidia GT200의 경우 30개, Evergreen의 경우 20개, Fermi의 경우 16개), ATI 용어로 SIMD 엔진으로 구성됩니다. 이 기사에서는 수백 개의 프로그램 스레드를 실행하고 일반 CPU가 할 수 있는 거의 모든 작업을 수행할 수 있지만 여전히 모든 작업을 수행할 수는 없기 때문에 이를 미니프로세서라고 부를 것입니다.

마케팅 이름은 혼란스럽습니다. 더 중요한 의미로 뺄셈과 곱셈이 가능한 기능 모듈의 수를 나타냅니다(예: 320개의 벡터 "코어"(코어)). 이 커널은 곡물과 비슷합니다. GPU를 동시에 많은 스레드를 실행하는 많은 코어가 있는 멀티 코어 프로세서로 생각하는 것이 좋습니다.

각 미니 프로세서에는 GT200의 경우 16KB, Evergreen의 경우 32KB, Fermi의 경우 64KB(기본적으로 프로그래밍 가능한 L1 캐시)의 로컬 메모리가 있습니다. 기존 CPU의 L1 캐시에 대한 접근 시간이 비슷하고, 기능 모듈에 최대한 빠르게 데이터를 전달하는 유사한 기능을 수행한다. Fermi 아키텍처에서 로컬 메모리의 일부는 일반 캐시로 구성될 수 있습니다. GPU에서 로컬 메모리는 실행 중인 스레드 간에 데이터를 빠르게 교환하는 데 사용됩니다. GPU 프로그램의 일반적인 방식 중 하나는 다음과 같습니다. 먼저 GPU의 전역 메모리에서 로컬 메모리로 데이터를 로드합니다. 이것은 위치하는 일반 비디오 메모리입니다(예: 시스템 메모리) "자체"프로세서와 별도로 - 비디오의 경우 비디오 카드의 텍스트 라이트에 여러 미세 회로에 의해 납땜됩니다. 다음으로 수백 개의 스레드가 이 데이터를 로컬 메모리에서 작업하고 결과를 글로벌 메모리에 쓴 후 CPU로 전송합니다. 로컬 메모리에서 데이터를 로드 및 언로드하기 위한 명령을 작성하는 것은 프로그래머의 책임입니다. 본질적으로 이것은 병렬 처리를 위한 [특정 작업의] 데이터 분할입니다. GPU는 또한 메모리에 대한 원자적 쓰기/읽기 명령을 지원하지만 비효율적이며 일반적으로 모든 미니프로세서의 계산 결과를 "접착"하기 위해 최종 단계에서 필요합니다.

로컬 메모리는 미니 프로세서에서 실행되는 모든 스레드에 공통적이므로 예를 들어 Nvidia 용어에서는 공유라고도 하며 로컬 메모리라는 용어는 정확히 반대를 의미합니다. 즉, 전역에서 별도의 스레드의 특정 개인 영역 메모리, 볼 수 있고 액세스할 수 있습니다. 그러나 로컬 메모리 외에도 미니 프로세서에는 모든 아키텍처에서 약 4배 더 큰 또 다른 메모리 영역이 있습니다. 실행중인 모든 쓰레드에 균등하게 나누어져 있으며, 변수를 저장하는 레지스터와 계산의 중간 결과를 저장하는 레지스터이다. 각 스레드에는 수십 개의 레지스터가 있습니다. 정확한 수는 미니프로세서가 실행 중인 스레드 수에 따라 다릅니다. 전역 메모리의 대기 시간이 수백 주기로 매우 높고 캐시가 없으면 중간 계산 결과를 저장할 곳이 없기 때문에 이 숫자는 매우 중요합니다.

GPU의 또 다른 중요한 기능은 "소프트" 벡터화입니다. 각 미니 프로세서에는 많은 수의 컴퓨팅 모듈(GT200의 경우 8개, Radeon의 경우 16개, Fermi의 경우 32개)이 있지만 동일한 프로그램 주소로 동일한 명령만 실행할 수 있습니다. 이 경우 피연산자는 다를 수 있으며 다른 스레드에는 고유한 스레드가 있습니다. 예를 들어, 지시 두 레지스터의 내용 추가: 모든 컴퓨팅 장치에서 동시에 실행되지만 다른 레지스터를 사용합니다. 데이터의 병렬 처리를 수행하는 GPU 프로그램의 모든 스레드는 일반적으로 프로그램 코드를 통해 병렬로 이동한다고 가정합니다. 따라서 모든 컴퓨팅 모듈이 균등하게 로드됩니다. 그리고 프로그램의 분기로 인해 스레드가 코드 실행 경로에서 분기되면 소위 직렬화가 발생합니다. 그러면 스레드가 실행을 위해 다른 명령을 제출하고 컴퓨팅 모듈 블록이 이미 말했듯이 하나의 주소가 있는 명령만 실행할 수 있기 때문에 모든 컴퓨팅 모듈이 사용되는 것은 아닙니다. 물론 동시에 성능은 최대값과 관련하여 떨어집니다.

이점은 벡터화가 완전히 자동이며 SSE, MMX 등을 사용하여 프로그래밍하지 않는다는 것입니다. 그리고 GPU 자체가 불일치를 처리합니다. 이론적으로 실행 모듈의 벡터 특성을 고려하지 않고 GPU용 프로그램을 작성할 수 있지만 그러한 프로그램의 속도는 그리 빠르지 않을 것입니다. 단점은 벡터의 너비가 크다는 것입니다. 기능 모듈의 명목상 수보다 많으며 Nvidia GPU의 경우 32개, Radeon의 경우 64개입니다. 스레드는 적절한 크기의 블록으로 처리됩니다. Nvidia는 이 스레드 블록을 워프, AMD - 웨이브 프론트라는 용어로 부릅니다. 이는 동일한 것입니다. 따라서 16개의 컴퓨팅 장치에서 "웨이브 프론트" 64개 스레드 길이는 4개의 사이클로 처리됩니다(일반적인 명령어 길이 가정). 저자는 이 경우에 워프라는 용어를 선호하는데, 이는 꼬인 로프로 묶인 밧줄을 나타내는 해상 용어 워프와 연관되기 때문입니다. 따라서 스레드는 "비틀어서" 완전한 번들을 형성합니다. 그러나 "파도 앞"은 바다와도 연관될 수 있습니다. 파도가 차례로 해안으로 밀려오는 것과 같은 방식으로 작동기에 지침이 도착합니다.

모든 스레드가 프로그램 실행에서 동일하게 진행되어(같은 위치에 있음) 동일한 명령을 실행하면 모든 것이 정상이지만 그렇지 않은 경우 속도가 느려집니다. 이 경우 동일한 워프 또는 웨이브 프론트의 스레드는 프로그램의 다른 위치에 있으며 동일한 값의 명령 번호(즉, 명령 포인터)를 갖는 스레드 그룹으로 나뉩니다. 그리고 이전과 마찬가지로 한 그룹의 스레드만 한 번에 실행됩니다. 모두 동일한 명령어를 실행하지만 피연산자는 다릅니다. 결과적으로 워프는 몇 배나 느리게 실행되고, 몇 개의 그룹으로 분할되는지, 그룹의 스레드 수는 중요하지 않습니다. 그룹이 하나의 스레드로만 구성되어 있어도 전체 워프로 실행하는 데 시간이 오래 걸립니다. 하드웨어에서는 특정 스레드를 마스킹하여 구현합니다. 즉, 명령은 정식으로 실행되지만 실행 결과는 어디에도 기록되지 않고 향후에도 사용되지 않습니다.

각 미니프로세서(Streaming MultiProcessor 또는 SIMD 엔진)는 주어진 시간에 하나의 워프(스레드 묶음)에만 속하는 명령을 실행하지만 실행 가능한 풀에는 수십 개의 활성 워프가 있습니다. 한 워프의 명령을 실행한 후 미니 프로세서는 이 워프 스레드의 다음 명령을 차례로 실행하지 않고 워프에 있는 다른 사람의 명령을 실행합니다. 그 워프는 프로그램에서 완전히 다른 위치에 있을 수 있습니다. 이는 워프 내부에서만 모든 스레드의 명령이 최대 속도로 실행되기 위해 동일해야 하기 때문에 속도에 영향을 미치지 않습니다.

이 경우 20개의 SIMD 엔진에는 각각 64개의 스레드가 있는 4개의 활성 웨이브 프론트가 있습니다. 각 스레드는 짧은 선으로 표시됩니다. 총계: 64×4×20=5120 스레드

따라서 각 워프 또는 웨이브 프론트가 32-64개의 ​​스레드로 구성되어 있는 경우 미니프로세서에는 거의 동시에 실행되는 수백 개의 활성 스레드가 있습니다. 아래에서 많은 수의 병렬 스레드가 약속하는 아키텍처상의 이점을 살펴보겠지만 먼저 GPU를 구성하는 미니 프로세서가 갖는 제한 사항을 고려할 것입니다.

중요한 것은 GPU에 함수 매개변수와 지역 변수를 저장할 수 있는 스택이 없다는 것입니다. 스택의 스레드 수가 많기 때문에 칩에 공간이 없습니다. 실제로 GPU는 100KB의 단일 스레드 스택 크기로 약 10,000개의 스레드를 동시에 실행하므로 총 용량은 1GB가 됩니다. 이는 모든 비디오 메모리의 표준 용량과 같습니다. 또한 GPU 코어 자체에 상당한 크기의 스택을 배치할 방법이 없습니다. 예를 들어, 스레드당 1000바이트의 스택을 넣으면 하나의 미니프로세서에만 1MB의 메모리가 필요합니다.

따라서 GPU 프로그램에는 재귀가 없으며 실제로 함수 호출로 전환할 수 없습니다. 모든 기능은 프로그램이 컴파일될 때 코드로 직접 대체됩니다. 이것은 GPU의 범위를 계산 작업으로 제한합니다. 알려진 작은 반복 깊이로 재귀 알고리즘에 전역 메모리를 사용하는 제한된 스택 에뮬레이션을 사용하는 것이 때때로 가능하지만 이것은 일반적인 GPU 응용 프로그램이 아닙니다. 이를 위해서는 CPU에 비해 ​​성공적인 가속을 보장하지 않고 구현 가능성을 탐색하는 알고리즘을 특별히 개발해야 합니다.

Fermi는 처음에 가상 기능을 사용하는 기능을 도입했지만 다시 각 스레드에 대한 크고 빠른 캐시가 부족하여 사용이 제한됩니다. 1536 스레드는 48KB 또는 16KB L1을 차지합니다. 즉, 프로그램의 가상 기능은 비교적 드물게 사용될 수 있습니다. CPU 버전으로.

따라서 GPU는 데이터가 로드되고 일부 알고리즘에 의해 처리되고 결과가 생성되는 계산 보조 프로세서로 제공됩니다.

아키텍처의 이점

그러나 GPU는 매우 빠릅니다. 그리고 이것에서 그는 높은 멀티 스레딩의 도움을 받았습니다. 많은 수의 활성 스레드를 통해 약 500 사이클에 해당하는 별도로 위치한 글로벌 비디오 메모리의 큰 대기 시간을 부분적으로 숨길 수 있습니다. 고밀도 코드에 특히 적합합니다. 산술 연산. 따라서 트랜지스터 비용이 많이 드는 L1-L2-L3 캐시 계층 구조가 필요하지 않습니다. 대신 많은 컴퓨팅 모듈을 칩에 배치하여 뛰어난 산술 성능을 제공할 수 있습니다. 그 동안 한 스레드 또는 워프의 명령이 실행되고 다른 수백 개의 스레드가 조용히 데이터를 기다리고 있습니다.

Fermi는 약 1MB의 두 번째 수준 캐시를 도입했지만 최신 프로세서의 캐시와 비교할 수는 없으며 코어 및 다양한 소프트웨어 트릭 간의 통신을 위한 것입니다. 그 크기를 수만 개의 모든 스레드로 나누면 각 스레드의 양이 매우 적습니다.

그러나 전역 메모리의 대기 시간 외에도 컴퓨팅 장치에는 숨겨야 하는 대기 시간이 훨씬 더 많습니다. 이것은 컴퓨팅 장치에서 첫 번째 수준 캐시, 즉 GPU의 로컬 메모리, 레지스터 및 명령어 캐시로의 칩 내 데이터 전송 지연입니다. 레지스터 파일과 로컬 메모리는 기능 모듈과 별도로 위치하며 액세스 속도는 약 12주기입니다. 그리고 다시 많은 수의 스레드, 활성 워프가 이 대기 시간을 효과적으로 숨길 수 있습니다. 또한 전체 GPU의 로컬 메모리에 대한 액세스의 총 대역폭(대역폭)은 구성하는 미니 프로세서의 수를 고려하여 최신 CPU의 첫 번째 수준 캐시에 대한 액세스 대역폭보다 훨씬 큽니다. GPU는 단위 시간당 훨씬 더 많은 데이터를 처리할 수 있습니다.

GPU에 많은 수의 병렬 스레드가 제공되지 않으면 마치 완전히 로드된 것처럼 동일한 속도로 작동하고 훨씬 적은 작업을 수행하기 때문에 성능이 거의 0에 가깝다고 즉시 말할 수 있습니다. 예를 들어 10,000개 대신 하나의 스레드만 남게 하면 모든 블록이 로드되지 않을 뿐만 아니라 모든 대기 시간도 영향을 받기 때문에 성능이 약 1,000배 떨어집니다.

대기 시간을 숨기는 문제는 최신 고주파 CPU에서도 심각하며 이를 제거하기 위해 심층 파이프라이닝, 비순차적 명령 실행(비순차적)과 같은 정교한 방법이 사용됩니다. 이를 위해서는 칩의 공간을 차지하는 복잡한 명령어 실행 스케줄러, 다양한 버퍼 등이 필요합니다. 이 모든 것은 단일 스레드 모드에서 최상의 성능을 위해 필요합니다.

그러나 GPU의 경우 이 모든 것이 필요하지 않으며 많은 수의 스레드가 있는 계산 작업의 경우 구조적으로 더 빠릅니다. 대신, 철학자의 돌이 납을 금으로 바꾸는 것처럼 멀티스레딩을 성능으로 변환합니다.

GPU는 원래 분명히 독립적이고 병렬로 실행될 수 있는 삼각형 픽셀에 대한 셰이더 프로그램을 최적으로 실행하도록 설계되었습니다. 그리고 이 상태에서 매우 강력한 컴퓨팅 장치에 다양한 기능(로컬 메모리 및 비디오 메모리에 대한 주소 지정 가능 액세스, 복잡한 명령 집합)을 추가하여 진화했습니다. 이 장치는 고도로 병렬 구현을 허용하는 알고리즘에만 여전히 효과적으로 적용될 수 있습니다. 제한된 양의 로컬 메모리 사용 메모리.

예시

가장 고전적인 GPU 문제 중 하나는 중력장을 생성하는 N개의 물체의 상호 작용을 계산하는 문제입니다. 그러나 예를 들어 지구-달-태양 시스템의 진화를 계산해야 하는 경우 GPU는 우리에게 나쁜 도우미입니다. 개체가 거의 없습니다. 각 개체에 대해 다른 모든 개체와의 상호 작용을 계산해야 하며 그 중 두 개만 있습니다. 모든 행성과 위성(약 200개 물체)이 있는 태양계의 운동의 경우 GPU는 여전히 효율적이지 않습니다. 그러나 다중 코어 프로세서는 스레드 관리에 대한 높은 오버헤드 비용으로 인해 모든 성능을 보여줄 수 없으며 단일 스레드 모드에서 작동합니다. 그러나 혜성과 소행성 벨트 개체의 궤적도 계산해야 하는 경우 필요한 수의 병렬 계산 스레드를 생성하기에 충분한 개체가 있기 때문에 이것은 이미 GPU의 작업입니다.

GPU는 수십만 개의 별 구상 성단의 충돌을 계산해야 하는 경우에도 잘 수행됩니다.

N-body 문제에서 GPU의 능력을 사용할 수 있는 또 다른 기회는 적은 수의 바디로 많은 개별 문제를 계산해야 할 때 나타납니다. 예를 들어, 초기 속도에 대한 다른 옵션에 대해 한 시스템의 진화를 계산하려는 경우입니다. 그러면 문제 없이 GPU를 효과적으로 사용할 수 있습니다.

AMD Radeon 마이크로아키텍처 세부 정보

우리는 GPU 구성의 기본 원칙을 고려했으며 처음에는 셰이더 프로그램이라는 하나의 대상 작업이 있었기 때문에 모든 제조업체의 비디오 가속기에 공통적입니다. 그러나 제조업체는 마이크로아키텍처 구현의 세부 사항에 대해 동의하지 않을 수 있음을 발견했습니다. 서로 다른 공급업체의 CPU는 때때로 매우 다르지만 Pentium 4 및 Athlon 또는 Core와 같이 호환되는 경우에도 마찬가지입니다. Nvidia의 아키텍처는 이미 널리 알려져 있습니다. 이제 Radeon을 살펴보고 이러한 공급업체의 접근 방식의 주요 차이점을 강조하겠습니다.

AMD 그래픽 카드는 DirectX 11 사양을 개척한 Evergreen 제품군 이후 범용 컴퓨팅에 대한 완전한 지원을 받아왔습니다.47xx 제품군 카드에는 여러 가지 중요한 제한 사항이 있으며 이에 대해서는 아래에서 설명합니다.

로컬 메모리 크기의 차이(Radeon의 경우 32KB, GT200의 경우 16KB, Fermi의 경우 64KB)는 일반적으로 근본적이지 않습니다. AMD의 경우 64개 스레드와 Nvidia의 경우 워프당 32개 스레드의 웨이브 프론트 크기도 있습니다. 거의 모든 GPU 프로그램을 쉽게 재구성하고 이러한 매개변수로 조정할 수 있습니다. 성능은 수십 퍼센트까지 변할 수 있지만 GPU의 경우 GPU 프로그램이 일반적으로 CPU의 경우보다 10배 느리게 실행되거나 10배 더 빠르거나 전혀 작동하지 않기 때문에 그렇게 중요하지 않습니다.

더 중요한 것은 사용 AMD 기술 VLIW(매우 긴 지시어). Nvidia는 스칼라 레지스터에서 작동하는 스칼라 단순 명령어를 사용합니다. 가속기는 단순한 클래식 RISC를 구현합니다. AMD 그래픽 카드는 GT200과 같은 수의 레지스터를 가지고 있지만 레지스터는 128비트 벡터입니다. 각 VLIW 명령어는 SSE와 유사한 여러 4성분 32비트 레지스터에서 작동하지만 VLIW의 기능은 훨씬 더 넓습니다. 이것은 SSE와 같은 SIMD(단일 명령 다중 데이터)가 아닙니다. 여기에서 각 피연산자 쌍에 대한 명령은 다를 수 있으며 종속될 수도 있습니다! 예를 들어, 레지스터 A의 구성 요소 이름을 a1, a2, a3, a4로 지정합니다. 레지스터 B의 경우 - 유사하게. 예를 들어 숫자 a1×b1+a2×b2+a3×b3+a4×b4 또는 2차원 벡터(a1×b1+a2×b2, a3×)와 같이 한 사이클에서 실행되는 단일 명령어로 계산할 수 있습니다. b3+a4×b4 ).

이것은 CPU보다 GPU의 주파수가 낮고 기술 프로세스가 크게 감소했기 때문에 가능했습니다. 지난 몇 년. 이것은 스케줄러가 필요하지 않으며 거의 ​​모든 것이 클럭당 실행됩니다.

벡터 명령을 사용하면 Radeon의 최대 단정밀도 성능은 테라플롭에서 매우 높습니다.

하나의 벡터 레지스터는 4개의 단정밀도 숫자 대신 하나의 배정밀도 숫자를 저장할 수 있습니다. 그리고 하나의 VLIW 명령어는 두 쌍의 double을 더하거나 두 숫자를 곱하거나 두 숫자를 곱하고 세 번째 숫자를 더할 수 있습니다. 따라서 double의 피크 성능은 float보다 약 5배 낮습니다. 구형 Radeon 모델의 경우 엔비디아 성능새로운 Fermi 아키텍처의 Tesla와 GT200 아키텍처의 더블 카드보다 훨씬 높은 성능. Fermi 기반 소비자 Geforce 비디오 카드에서 이중 계산의 최대 속도는 4배 감소했습니다.


Radeon 작업의 개략도. 병렬로 실행되는 20개 중 1개의 미니프로세서만 표시됩니다.

CPU 제조업체(우선 x86 호환 제조업체)와 달리 GPU 제조업체는 호환성 문제에 구속되지 않습니다. GPU 프로그램은 먼저 일부 중간 코드로 컴파일되고 프로그램이 실행될 때 드라이버는 이 코드를 특정 기계 명령어로 컴파일합니다. 특정 모델. 위에서 설명한 것처럼 GPU 제조업체는 GPU에 대한 편리한 ISA(명령 집합 아키텍처)를 발명하고 이를 세대에서 세대로 변경하여 이를 활용했습니다. 어쨌든 이것은 디코더의 부족(불필요한)으로 인해 성능의 일부를 추가했습니다. 그러나 AMD는 더 나아가 기계 코드로 명령을 배열하기 위한 자체 형식을 발명했습니다. 그것들은 (프로그램 목록에 따라) 순차적으로 배열되지 않고 섹션으로 배열됩니다.

먼저 다른 분기 분기에 해당하는 연속 산술 명령어 섹션에 대한 링크가 있는 조건부 점프 명령어 섹션이 있습니다. 이를 VLIW 번들(VLIW 명령어 번들)이라고 합니다. 이 섹션에는 레지스터 또는 로컬 메모리의 데이터가 있는 산술 명령어만 포함됩니다. 이러한 조직은 지침의 흐름과 실행 단위로의 전달을 단순화합니다. 이것은 VLIW 명령어가 상대적으로 크다는 점을 감안할 때 훨씬 더 유용합니다. 메모리 액세스 명령에 대한 섹션도 있습니다.

조건 분기 명령 섹션
섹션 0분기 0연속 산술 명령어의 섹션 #3에 대한 링크
섹션 1분기 1섹션 #4에 대한 링크
섹션 2분기 2섹션 #5에 대한 링크
연속 산술 명령어 섹션
섹션 3VLIW 명령어 0VLIW 명령 1VLIW 명령 2VLIW 명령 3
섹션 4VLIW 명령 4VLIW 명령 5
섹션 5VLIW 명령 6VLIW 명령 7VLIW 명령 8VLIW 명령 9

두 제조업체(Nvidia 및 AMD 모두)의 GPU에는 여러 주기의 단정밀도 숫자에 대한 기본 수학 함수, 제곱근, 지수, 로그, 사인 및 코사인을 빠르게 계산하기 위한 내장 명령어도 있습니다. 이를 위한 특별한 컴퓨팅 블록이 있습니다. 지오메트리 셰이더에서 이러한 함수의 빠른 근사치를 구현해야 할 필요성에서 "출시"되었습니다.

누군가 GPU가 그래픽에 사용된다는 사실을 모르고 기술적 특성만 알게 되더라도 이 기호를 통해 이러한 컴퓨팅 보조 프로세서가 비디오 가속기에서 유래했음을 추측할 수 있었습니다. 그와 유사하게, 해양 포유류의 일부 특성으로 인해 과학자들은 그들의 조상이 육상 생물이라고 믿게 되었습니다.

그러나 장치의 그래픽 원점을 드러내는 더 분명한 기능은 쌍선형 보간을 지원하는 2차원 및 3차원 텍스처를 읽기 위한 블록입니다. 읽기 전용 데이터 배열을 더 빠르고 쉽게 읽을 수 있기 때문에 GPU 프로그램에서 널리 사용됩니다. 중 하나 표준 옵션 GPU 응용 프로그램의 동작은 초기 데이터 배열을 읽고 계산 코어에서 처리하고 결과를 다른 배열에 쓴 다음 CPU로 다시 전송하는 것입니다. 이러한 체계는 GPU 아키텍처에 편리하기 때문에 표준적이고 일반적입니다. 데이터 종속성을 포함하는 전역 메모리의 하나의 큰 영역에 집중적인 읽기 및 쓰기가 필요한 작업은 GPU에서 병렬화하고 효율적으로 구현하기 어렵습니다. 또한 성능은 매우 큰 글로벌 메모리의 대기 시간에 따라 크게 달라집니다. 그러나 작업이 "데이터 읽기 - 처리 - 결과 쓰기" 패턴으로 설명되는 경우 GPU에서 실행하면 거의 확실하게 큰 향상을 얻을 수 있습니다.

GPU의 텍스처 데이터의 경우 첫 번째 및 두 번째 수준의 작은 캐시로 구성된 별도의 계층이 있습니다. 또한 텍스처를 사용하여 가속을 제공합니다. 이 계층 구조는 원래 텍스처에 대한 액세스의 지역성을 활용하기 위해 GPU에 나타났습니다. 분명히 한 픽셀을 처리한 후 인접 픽셀(높은 확률로)에는 밀접하게 배치된 텍스처 데이터가 필요합니다. 그러나 기존 컴퓨팅을 위한 많은 알고리즘은 유사한 데이터 액세스 특성을 가지고 있습니다. 따라서 그래픽의 텍스처 캐시가 매우 유용할 것입니다.

Nvidia 및 AMD 카드의 L1-L2 캐시 크기는 거의 동일하지만 게임 그래픽 측면에서 최적의 요구 사항으로 인해 분명히 발생하지만 이러한 캐시에 대한 액세스 대기 시간은 크게 다릅니다. Nvidia의 액세스 대기 시간은 더 높으며 Geforce의 텍스처 캐시는 데이터 액세스 속도를 직접적으로 높이는 것이 아니라 주로 메모리 버스의 부하를 줄이는 데 도움이 됩니다. 이것은 그래픽 프로그램에서는 눈에 띄지 않지만 범용 프로그램에서는 중요합니다. Radeon에서 텍스처 캐시의 대기 시간은 더 낮지만 미니 프로세서의 로컬 메모리 대기 시간은 더 높습니다. 예는 다음과 같습니다. Nvidia 카드에서 최적의 행렬 곱셈을 위해서는 로컬 메모리를 사용하여 블록별로 행렬을 로드하는 것이 좋으며 AMD의 경우 지연 시간이 짧은 텍스처 캐시에 의존하여 행렬 요소를 다음과 같이 읽는 것이 좋습니다. 필요. 그러나 이것은 이미 근본적으로 GPU로 전송된 알고리즘에 대한 다소 미묘한 최적화입니다.

이 차이는 3D 텍스처를 사용할 때도 나타납니다. AMD에 심각한 이점을 보여준 최초의 GPU 컴퓨팅 벤치마크 중 하나는 3차원 데이터 배열과 함께 작동하기 때문에 3D 텍스처만 사용했습니다. 그리고 Radeon의 텍스처 액세스 대기 시간은 훨씬 더 빠르며 3D 케이스는 추가로 하드웨어에서 더 최적화됩니다.

다양한 회사의 하드웨어에서 최대 성능을 얻으려면 특정 카드에 대한 응용 프로그램의 일부 조정이 필요하지만 원칙적으로 GPU 아키텍처용 알고리즘 개발보다 중요하지 않습니다.

Radeon 47xx 시리즈 제한 사항

이 제품군에서는 GPU 컴퓨팅에 대한 지원이 불완전합니다. 세 가지가 있습니다 중요한 순간. 첫째, 로컬 메모리가 없습니다. 즉, 물리적으로 존재하지만 최신 GPU 프로그램 표준에서 요구하는 범용 액세스가 없습니다. 전역 메모리에서 프로그래밍 방식으로 에뮬레이트되므로 모든 기능을 갖춘 GPU와 달리 사용하면 이점이 없습니다. 두 번째 요점은 다양한 원자 메모리 연산 명령어와 동기화 명령어에 대한 지원이 제한적이라는 것입니다. 그리고 세 번째 포인트는 꽤 작은 크기명령어 캐시: 특정 프로그램 크기부터 시작하여 속도가 몇 배 느려집니다. 다른 사소한 제한 사항도 있습니다. GPU에 이상적으로 적합한 프로그램만이 이 비디오 카드에서 잘 작동한다고 말할 수 있습니다. 비디오 카드는 레지스터로만 작동하는 간단한 테스트 프로그램에서 Gigaflops에서 좋은 결과를 보여줄 수 있지만 복잡한 것을 효과적으로 프로그래밍하는 것은 문제가 있습니다.

에버그린의 장점과 단점

AMD와 Nvidia 제품을 비교하면 GPU 컴퓨팅 측면에서 5xxx 시리즈는 매우 강력한 GT200처럼 보입니다. 너무 강력해서 최대 성능에서 페르미를 약 2.5배 능가합니다. 특히 새로운 Nvidia 비디오 카드의 매개변수가 절단된 후 코어 수가 감소했습니다. 그러나 Fermi에서 L2 캐시의 출현은 GPU에서 일부 알고리즘의 구현을 단순화하여 GPU의 범위를 확장합니다. 흥미롭게도 이전 세대 GT200 CUDA 프로그램에 대해 잘 최적화된 Fermi의 아키텍처 혁신은 종종 아무 효과가 없었습니다. 메모리 대역폭이 증가하지 않았기 때문에(또는 다른 이유로) 컴퓨팅 모듈 수의 증가에 비례하여 가속화되었습니다.

그리고 GPU 아키텍처에 잘 맞고 벡터 특성이 뚜렷한 작업(예: 행렬 곱셈)에서 Radeon은 이론적인 피크에 비교적 가까운 성능을 보여주고 Fermi를 추월합니다. 멀티 코어 CPU는 말할 것도 없습니다. 특히 단정밀도 숫자 문제에서.

그러나 Radeon은 더 작은 다이 면적, 더 적은 열 발산, 전력 소비, 더 높은 수율 및 그에 따른 더 낮은 비용을 가지고 있습니다. 그리고 3D 그래픽의 문제에서 직접적으로 페르미 게인이 있는 경우 수정 영역의 차이보다 훨씬 적습니다. 이는 주로 미니프로세서당 16개의 컴퓨팅 유닛, 64개의 스레드 웨이브 프런트 및 VLIW 벡터 명령어를 포함하는 Radeon의 컴퓨팅 아키텍처가 주요 작업인 컴퓨팅 그래픽 셰이더에 적합하기 때문입니다. 대다수의 경우 일반 사용자게임 성능과 가격이 우선입니다.

전문적이고 과학적인 프로그램의 관점에서 Radeon 아키텍처는 원칙적으로 GPU 아키텍처에 잘 맞는 작업에서 최고의 가격 대비 성능 비율, 와트당 성능 및 절대 성능을 제공하고 병렬화 및 벡터화를 허용합니다.

예를 들어, 완전히 병렬이고 쉽게 벡터화할 수 있는 키 선택 문제에서 Radeon은 Geforce보다 몇 배 빠르며 CPU보다 수십 배 빠릅니다.

이는 이전에 수학 보조 프로세서가 별도의 칩에서 프로세서 코어로 이전된 것처럼 GPU가 CPU를 보완하고 향후 CPU 코어 자체에 통합되어야 하는 일반적인 AMD Fusion 개념에 해당합니다(이는 약 20년 전, 최초의 펜티엄 프로세서가 등장하기 전). GPU가 통합됩니다 그래픽 코어및 스트리밍 작업을 위한 벡터 코프로세서.

Radeon은 기능 모듈에 의해 실행될 때 서로 다른 파면의 명령어를 혼합하는 까다로운 기술을 사용합니다. 지침이 완전히 독립적이므로 수행하기 쉽습니다. 원리는 최신 CPU에 의한 독립적인 명령의 파이프라인 실행과 유사합니다. 분명히 이것은 복잡한 멀티바이트 벡터 VLIW 명령어를 효율적으로 실행하는 것을 가능하게 합니다. CPU에서는 독립적인 명령을 식별하기 위한 정교한 스케줄러가 필요하거나 다른 스레드에서 알려진 독립 명령을 CPU에 제공하는 하이퍼 스레딩 기술을 사용해야 합니다.

측정 0바 1측정 2측정 3바 4바 5바 6바 7VLIW 모듈
웨이브 프론트 0웨이브 프론트 1웨이브 프론트 0웨이브 프론트 1웨이브 프론트 0웨이브 프론트 1웨이브 프론트 0웨이브 프론트 1
인스트럭션 0인스트럭션 0인스트럭션 16인스트럭션 16인스트럭션 32인스트럭션 32인스트럭션 48인스트럭션 48VLIW0
인스트럭션 하나VLIW1
인스트럭션 2VLIW2
인스트럭션 삼VLIW3
인스트럭션 네VLIW4
인스트럭션 5VLIW5
인스트럭션 6VLIW6
인스트럭션 7VLIW7
인스트럭션 여덟VLIW8
인스트럭션 9VLIW9
인스트럭션 십VLIW10
인스트럭션 열하나VLIW11
인스트럭션 12VLIW12
인스트럭션 13VLIW13
인스트럭션 십사VLIW14
인스트럭션 열 다섯VLIW15

각각 64개의 연산으로 구성된 2개의 파면에 대한 128개의 명령어는 8개의 사이클에서 16개의 VLIW 모듈에 의해 실행됩니다. 대안이 있으며 각 모듈에는 실제로 전체 명령을 실행하기 위한 두 개의 주기가 있습니다. 단, 두 번째 주기에서 새 모듈을 병렬로 실행하기 시작합니다. 이것은 a1×a2+b1×b2+c1×c2+d1×d2와 같은 VLIW 명령어를 빠르게 실행하는 데 도움이 될 것입니다. 즉, 8개의 사이클에서 이러한 명령어 8개를 실행합니다. (공식적으로는 시계당 하나씩입니다.)

Nvidia는 분명히 이 기술이 없습니다. 그리고 VLIW가 없는 경우 스칼라 명령어를 사용하는 고성능에는 높은 주파수의 작동이 필요하며, 이는 자동으로 열 발산을 증가시키고 프로세스에 높은 요구 사항을 부과합니다(회로가 더 높은 주파수에서 실행되도록 하기 위해).

GPU 컴퓨팅 측면에서 Radeon의 단점은 분기를 크게 싫어한다는 것입니다. GPU는 일반적으로 명령을 실행하기 위한 위의 기술로 인해 분기를 선호하지 않습니다. 즉, 하나의 프로그램 주소를 가진 스레드 그룹에 의해 즉시 실행됩니다. (그런데 이 기술을 SIMT: 단일 명령어 - 다중 스레드(하나의 명령어 - 많은 스레드)라고 하며 하나의 명령어가 다른 데이터로 하나의 작업을 수행하는 SIMD와 유사합니다.) . 프로그램이 완전히 벡터가 아닌 경우 날실 또는 파면의 크기가 클수록 더 나빠집니다. 프로그램을 통한 경로가 분기될 때 인접 스레드가 형성되기 때문입니다. 더 많은 그룹, 순차적으로 실행(직렬화)해야 합니다. 모든 스레드가 분산되었다고 가정하고 워프 크기가 ​​32 스레드인 경우 프로그램은 32배 느리게 실행됩니다. 그리고 사이즈 64의 경우 라데온처럼 64배 느립니다.

이것은 눈에 띄지만 "싫어요"의 유일한 표현은 아닙니다. Nvidia 비디오 카드에서 각 기능 모듈(CUDA 코어라고도 함)에는 특수 분기 처리 장치가 있습니다. 그리고 16개의 컴퓨팅 모듈용 Radeon 비디오 카드에는 분기 제어 장치가 2개뿐입니다(산술 장치 영역에서 파생됨). 따라서 조건 분기 명령의 간단한 처리조차도 결과가 웨이브 프론트의 모든 스레드에 대해 동일하더라도 추가 시간이 걸립니다. 그리고 속도가 떨어집니다.

AMD는 CPU도 제조합니다. 그들은 분기가 많은 프로그램의 경우 CPU가 여전히 더 적합하고 GPU는 순수한 벡터 프로그램용이라고 믿습니다.

따라서 Radeon은 전반적으로 덜 효율적인 프로그래밍을 제공하지만 많은 경우에 더 나은 가격 대비 성능 비율을 제공합니다. 다시 말해, Fermi에서 효과적으로 실행할 수 있는 프로그램보다 CPU에서 Radeon으로 효율적으로(이롭게) 마이그레이션할 수 있는 프로그램이 더 적습니다. 그러나 다른 한편으로 효과적으로 전송할 수 있는 것들은 여러 면에서 Radeon에서 더 효율적으로 작동할 것입니다.

GPU 컴퓨팅용 API

그들 자신 기술 사양 Radeon은 GPU 컴퓨팅을 이상화하고 절대화할 필요가 없더라도 매력적으로 보입니다. 그러나 성능에 대해 덜 중요한 것은 GPU 프로그램을 개발하고 실행하는 데 필요한 소프트웨어입니다. 고급 언어 및 런타임의 컴파일러, 즉 CPU에서 실행되는 프로그램의 일부와 GPU 간에 상호 작용하는 드라이버입니다. 그 자체. CPU의 경우보다 훨씬 더 중요합니다. CPU는 데이터 전송을 관리하기 위해 드라이버가 필요하지 않으며 컴파일러의 관점에서 GPU가 더 까다롭습니다. 예를 들어, 컴파일러는 계산의 중간 결과를 저장하기 위해 최소한의 레지스터를 사용해야 하며, 다시 최소한의 레지스터를 사용하여 신중하게 함수 호출을 인라인해야 합니다. 결국 쓰레드가 사용하는 레지스터가 적을수록 더 많은 쓰레드를 실행할 수 있고 GPU를 더 많이 로드하여 메모리 액세스 시간을 더 잘 숨길 수 있습니다.

따라서 Radeon 제품에 대한 소프트웨어 지원은 여전히 ​​하드웨어 개발보다 뒤쳐져 있습니다. (Nvidia의 경우 하드웨어 출시가 지연되고 제품이 벗겨진 형태로 출시된 것과는 대조적입니다.) 최근에는 AMD의 OpenCL 컴파일러가 베타 상태였으며 많은 결함이 있었습니다. 너무 자주 잘못된 코드를 생성하거나 올바른 소스 코드에서 코드 컴파일을 거부하거나 자체적으로 오류가 발생하여 충돌했습니다. 봄이 끝나갈 무렵에야 고성능의 릴리스가 나왔습니다. 또한 오류가 없는 것은 아니지만 오류가 훨씬 적으며 일반적으로 정확성 직전에 무언가를 프로그래밍하려고 할 때 부업으로 나타납니다. 예를 들어, 4바이트 4성분 변수를 지정하는 uchar4 유형으로 작업합니다. 이 유형은 OpenCL 사양에 있지만 레지스터가 128비트이기 때문에 Radeon에서 작업할 가치가 없습니다. 동일한 4개의 구성 요소이지만 32비트입니다. 그리고 그러한 uchar4 변수는 여전히 전체 레지스터를 차지할 것이며 개별 바이트 구성요소를 패킹하고 액세스하는 추가 작업만 계속 필요할 것입니다. 컴파일러에는 버그가 없어야 하지만 버그가 없는 컴파일러는 없습니다. 11 버전 이후의 인텔 컴파일러도 컴파일 오류가 있습니다. 확인된 버그는 가을이 가까워지면 출시될 다음 릴리스에서 수정됩니다.

하지만 아직 개선해야 할 부분이 많다. 예를 들어 지금까지 Radeon용 표준 GPU 드라이버는 OpenCL을 사용한 GPU 컴퓨팅을 지원하지 않습니다. 사용자는 추가 특수 패키지를 다운로드하여 설치해야 합니다.

그러나 가장 중요한 것은 함수 라이브러리가 없다는 것입니다. 배정밀도 실수의 경우 사인, 코사인 및 지수조차 없습니다. 음, 이것은 행렬 덧셈/곱셈에는 필요하지 않지만 더 복잡한 것을 프로그래밍하려면 모든 기능을 처음부터 작성해야 합니다. 또는 새 SDK 릴리스를 기다리십시오. ACML 곧 출시 예정( AMD 코어 Math Library) 기본 행렬 함수를 지원하는 Evergreen GPU 제품군용.

기사 작성자에 따르면 현재 Direct Compute 5.0 API의 사용은 Radeon 비디오 카드 프로그래밍에 실제적인 것으로 보이며 Windows 7 플랫폼에 대한 방향 및 제한 사항을 자연스럽게 고려합니다. 윈도우 비스타. Microsoft는 컴파일러를 만드는 데 많은 경험을 가지고 있으며 곧 완전한 기능을 갖춘 릴리스를 기대할 수 있습니다. Microsoft는 이에 직접적인 관심을 갖고 있습니다. 그러나 Direct Compute는 대화형 응용 프로그램의 요구 사항에 중점을 둡니다. 예를 들어 표면 위의 액체 흐름과 같이 무언가를 계산하고 결과를 즉시 시각화하는 것입니다. 이것은 단순히 계산에 사용할 수 없다는 것을 의미하지는 않지만 이것이 본래의 목적은 아닙니다. 예를 들어 Microsoft는 현재 AMD에 없는 라이브러리 기능을 Direct Compute에 추가할 계획이 없습니다. 즉, 이제 Radeon에서 효과적으로 계산할 수 있는 것(일부 매우 정교하지 않은 프로그램)은 OpenCL보다 훨씬 간단하고 더 안정적이어야 하는 Direct Compute에서도 구현할 수 있습니다. 또한 완전히 이식 가능하며 Nvidia와 AMD 모두에서 실행되므로 프로그램을 한 번만 컴파일하면 됩니다. 반면 Nvidia와 AMD의 OpenCL SDK 구현은 정확히 호환되지 않습니다. (AMD OpenCL SDK를 사용하여 AMD 시스템에서 OpenCL 프로그램을 개발하면 Nvidia에서 쉽게 실행되지 않을 수 있습니다. Nvidia SDK를 사용하여 동일한 텍스트를 컴파일해야 할 수도 있습니다. 물론 그 반대도 마찬가지입니다. )

그런 다음 OpenCL은 광범위한 시스템을 위한 범용 프로그래밍 언어 및 API가 되도록 의도되었기 때문에 OpenCL에는 많은 중복 기능이 있습니다. 그리고 GPU, CPU, 그리고 셀. 따라서 일반적인 사용자 시스템(프로세서와 비디오 카드)을 위한 프로그램을 작성하려는 경우 OpenCL은 말하자면 "매우 생산적"인 것 같지 않습니다. 각 함수에는 10개의 매개변수가 있으며 그 중 9개는 0으로 설정해야 합니다. 그리고 각 매개변수를 설정하려면 매개변수도 있는 특수 함수를 호출해야 합니다.

그리고 Direct Compute의 가장 중요한 현재 장점은 사용자가 특별한 패키지를 설치할 필요가 없다는 것입니다. 필요한 모든 것이 이미 DirectX 11에 있습니다.

GPU 컴퓨팅 개발의 문제점

개인용 컴퓨터 분야를 들자면, 기존의 듀얼코어 프로세서에서는 많은 연산력을 필요로 하고 심각하게 부족한 작업이 많지 않은 상황이다. 대식가지만 서투른 괴물들이 바다에서 육지로 기어나와 육지에서 먹을 것이 거의 없는 것 같았다. 그리고 지구 표면의 원시 거처는 크기가 줄어들고 있으며 천연 자원이 부족할 때 항상 발생하는 것처럼 덜 소비하는 법을 배우고 있습니다. 오늘날에도 10-15년 전과 동일한 성능 요구 사항이 있었다면 GPU 컴퓨팅은 대성공을 거두었을 것입니다. 따라서 호환성 문제와 GPU 프로그래밍의 상대적 복잡성이 전면에 나타납니다. 빠르지만 GPU에서만 실행되는 프로그램보다 모든 시스템에서 실행되는 프로그램을 작성하는 것이 좋습니다.

GPU에 대한 전망은 성능에 대한 수요가 더 많기 때문에 전문 애플리케이션 및 워크스테이션 부문에서의 사용 측면에서 다소 더 좋습니다. GPU 지원 3D 편집기용 플러그인이 등장하고 있습니다. 예를 들어 레이 트레이싱을 사용한 렌더링용 - 일반 GPU 렌더링과 혼동하지 마세요! 복잡한 효과를 더 빠르게 생성하면서 2D 및 프리젠테이션 편집자에게도 무언가가 나타납니다. 비디오 처리 프로그램도 점차 GPU에 대한 지원을 확보하고 있습니다. 위의 작업은 병렬 특성의 관점에서 GPU 아키텍처에 잘 맞지만 이제 모든 CPU 기능에 대해 매우 큰 코드 기반이 생성, 디버깅 및 최적화되었으므로 좋은 GPU 구현이 나타나는 데 시간이 걸립니다.

이 세그먼트에서는 제한된 양의 비디오 메모리(기존 GPU의 경우 약 1GB)와 같은 GPU의 이러한 약점도 나타납니다. GPU 프로그램의 성능을 저하시키는 주요 요인 중 하나는 느린 버스를 통해 CPU와 GPU 간에 데이터를 교환해야 하고 제한된 메모리 양으로 인해 더 많은 데이터를 전송해야 한다는 것입니다. 그리고 여기에서 GPU와 CPU를 하나의 모듈에 결합하는 AMD의 개념은 유망해 보입니다. 더 낮은 대기 시간으로 공유 메모리에 쉽고 간단하게 액세스하기 위해 높은 대역폭의 그래픽 메모리를 희생할 수 있습니다. 현재 DDR5 비디오 메모리의 이 높은 대역폭은 직접적으로 훨씬 더 수요가 많습니다. 그래픽 프로그램대부분의 GPU 컴퓨팅 프로그램보다 일반적으로, 공통 메모리 GPU와 CPU는 단순히 GPU의 범위를 크게 확장하여 프로그램의 작은 하위 작업에서 컴퓨팅 기능을 사용할 수 있도록 합니다.

그리고 대부분의 GPU는 과학 컴퓨팅 분야에서 수요가 많습니다. 여러 GPU 기반 슈퍼컴퓨터가 이미 구축되어 매트릭스 연산 테스트에서 매우 높은 결과를 보여줍니다. 과학적 문제는 너무 다양하고 많기 때문에 GPU 아키텍처에 완벽하게 맞는 집합이 항상 있으므로 GPU를 사용하면 고성능을 쉽게 얻을 수 있습니다.

현대 컴퓨터의 모든 작업 중 하나를 선택하면 우리가 살고 있는 세계의 이미지인 컴퓨터 그래픽이 됩니다. 그리고 이를 위한 최적의 아키텍처는 나쁘지 않습니다. 이것은 특별히 설계된 하드웨어가 보편적이고 다양한 작업에 최적화되어야 하는 매우 중요하고 기본적인 작업입니다. 또한 비디오 카드는 성공적으로 진화하고 있습니다.

가장 중 하나 숨겨진 기능, Windows 10의 최근 업데이트에서 는 GPU(그래픽 처리 장치)를 사용하는 응용 프로그램을 확인하는 기능입니다. 작업 관리자를 열어 본 적이 있다면 CPU 사용량을 확인하여 CPU를 가장 많이 사용하는 응용 프로그램을 확인했을 것입니다. 에 최신 업데이트유사한 기능을 추가했지만 GPU GPU용입니다. 타사 소프트웨어를 다운로드하지 않고도 GPU에서 소프트웨어와 게임이 얼마나 집중적인지 이해하는 데 도움이 됩니다. CPU를 GPU로 오프로드하는 데 도움이 되는 또 다른 흥미로운 기능이 있습니다. 선택 방법을 읽는 것이 좋습니다.

작업 관리자에 GPU가 없는 이유는 무엇입니까?

불행히도 모든 그래픽 카드가 GPU를 읽는 데 필요한 통계를 Windows에 제공할 수 있는 것은 아닙니다. 확실히 DirectX 진단 도구를 사용하여 이 기술을 빠르게 테스트할 수 있습니다.

  1. "를 클릭하십시오. 시작"그리고 검색에 쓰기 dxdiag DirectX 진단 도구를 실행합니다.
  2. 탭으로 이동 " 화면",열 오른쪽 운전사"당신은 가지고 있어야 WDDM 모델작업 관리자에서 GPU 그래프를 사용하려면 2.0 이상 버전을 사용해야 합니다.

작업 관리자에서 GPU 그래프 활성화

각 응용 프로그램의 GPU 사용량을 보려면 작업 관리자를 열어야 합니다.

  • 누르기 버튼 조합 Ctrl + Shift + Esc작업 관리자를 엽니다.
  • 딸깍 하는 소리 마우스 오른쪽 버튼으로 클릭빈 필드의 작업 관리자를 클릭하십시오 " 이름"드롭다운 메뉴에서 확인 GPU.당신은 또한 참고할 수 있습니다 GPU 코어어떤 프로그램이 그것을 사용하고 있는지 확인합니다.
  • 이제 작업 관리자에서 GPU 그래프와 GPU 코어가 오른쪽에 표시됩니다.


전체 GPU 성능 보기

전체 GPU 사용량을 추적하여 과부하 상태에서 모니터링하고 분석할 수 있습니다. 이 경우 "에서 필요한 모든 것을 볼 수 있습니다. 성능"선택하여 그래픽 프로세서.


각 GPU 요소는 개별 그래프로 세분화되어 GPU 사용 방식에 대한 더 많은 통찰력을 제공합니다. 표시되는 차트를 변경하려면 각 작업의 제목 옆에 있는 작은 화살표를 클릭하면 됩니다. 이 화면에는 DXDiag 또는 장치 관리자를 사용하는 대신 사용할 수 있는 드라이버 버전과 날짜도 표시됩니다.


코어가 너무 많지는 않습니다...

최신 GPU는 기가바이트의 데이터를 씹을 수 있는 엄청나게 빠른 짐승입니다. 그러나 사람은 교활하고 아무리 자라도 컴퓨팅 파워, 점점 더 어려운 일들이 생겨서 최적화가 필요하다는 아쉬움을 안고 말해야 하는 순간이 옵니다 🙁

이 기사에서는 GPU 최적화 이론과 기본 규칙을 보다 쉽게 ​​탐색할 수 있도록 기본 개념을 설명하여 이러한 개념에 덜 자주 액세스해야 합니다.

GPU가 처리가 필요한 대량의 데이터를 처리하는 데 효과적인 이유:

  • 작업을 병렬로 실행할 수 있는 좋은 기회가 있습니다(많은 프로세서).
  • 높은 메모리 대역폭

메모리 대역폭- 이것은 시간 단위, 초 또는 프로세서 주기당 얼마나 많은 정보(비트 또는 기가바이트)를 전송할 수 있는지입니다.

최적화 작업 중 하나는 최대 처리량을 사용하여 성능을 높이는 것입니다. 처리량(이상적으로는 메모리 대역폭과 같아야 합니다).

대역폭 사용을 개선하려면:

  • 정보의 양을 늘리십시오 - 대역폭을 최대로 사용하십시오(예: 각 스트림은 float4에서 작동함).
  • 대기 시간 감소 - 작업 간의 지연

지연 시간- 컨트롤러가 특정 메모리 셀을 요청한 순간과 프로세서가 명령을 실행하기 위해 데이터를 사용할 수 있게 된 순간 사이의 시간 간격. 우리는 어떤 식으로든 지연 자체에 영향을 줄 수 없습니다. 이러한 제한은 하드웨어 수준에서 존재합니다. 이 지연으로 인해 프로세서가 여러 스레드를 동시에 서비스할 수 있습니다. 스레드 A는 메모리 할당을 요청하고 스레드 B는 무언가를 계산할 수 있으며 스레드 C는 요청된 데이터가 도착할 때까지 기다릴 수 있습니다.

동기화를 사용하는 경우 대기 시간을 줄이는 방법:

  • 블록의 스레드 수 줄이기
  • 블록 그룹 수 증가

GPU 리소스를 최대한 사용 - GPU 점유

최적화에 대한 고급 대화에서 용어가 자주 깜박입니다. GPU 점유또는 커널 점유- 비디오 카드의 용량-자원 사용의 효율성을 반영합니다. 이와 별도로 모든 자원을 사용한다고 해서 올바르게 사용하고 있는 것은 아님을 알려드립니다.

GPU의 컴퓨팅 성능은 프로그램을 만들 때 계산에 욕심 많은 수백 개의 프로세서입니다. 커널(커널) - 부하를 분산시키는 부담은 프로그래머의 어깨에 있습니다. 실수로 인해 대부분의 귀중한 리소스가 이유 없이 유휴 상태가 될 수 있습니다. 이제 그 이유를 설명하겠습니다. 멀리서 시작해야 합니다.

워프( 경사 엔비디아 용어로, 웨이브프론트 - AMD 용어로) - 프로세서에서 동일한 커널 기능을 동시에 수행하는 스레드 집합입니다. 프로그래머가 블록으로 결합한 스레드는 스레드 스케줄러(각 다중 프로세서에 대해 별도로)에 의해 워프로 분할됩니다. 한 워프가 실행되는 동안 두 번째 워프는 메모리 요청이 처리되기를 기다리는 등입니다. 일부 워프 스레드가 여전히 계산을 수행하고 있고 다른 스레드는 이미 최선을 다한 경우 일반적으로 유휴 전력이라고 하는 컴퓨팅 리소스의 비효율적인 사용이 있습니다.

모든 동기화 지점, 모든 논리 분기가 이러한 유휴 상황을 만들 수 있습니다. 최대 분기(실행 논리의 분기)는 워프의 크기에 따라 다릅니다. NVidia GPU의 경우 32이고 AMD의 경우 64입니다.

워프 실행 중 다중 프로세서 다운타임을 줄이려면:

  • 대기 시간 장벽 최소화
  • 커널 함수에서 실행 로직의 발산 최소화

이 문제를 효과적으로 해결하려면 뒤틀림이 어떻게 형성되는지 이해하는 것이 좋습니다(여러 차원의 경우). 사실 순서는 간단합니다. 처음에는 X, 다음은 Y, 마지막은 Z입니다.

코어는 64×16 블록으로 시작되며 스레드는 X, Y, Z 순서로 워프로 분할됩니다. 처음 64개 요소는 두 개의 워프로 분할된 다음 두 번째 워프로 분할됩니다.

커널은 16x64 블록으로 시작합니다. 첫 번째 및 두 번째 16개 요소는 첫 번째 날실에 추가되고 세 번째 및 네 번째 요소는 두 번째 날실에 추가되는 식입니다.

분기를 줄이는 방법(분기가 항상 중요한 성능 손실의 원인은 아님을 기억하십시오)

  • 인접한 스레드가 서로 다른 실행 경로를 가질 때 - 많은 조건과 전환이 있을 때 - 재구성 방법을 찾습니다.
  • 언밸런스한 스레드 로드를 찾아 과감히 제거합니다(이는 조건이 있을 뿐만 아니라 이러한 조건 때문에 첫 번째 스레드는 항상 무언가를 계산하고 다섯 번째 스레드는 이 조건에 속하지 않고 유휴 상태일 때입니다)

GPU 리소스를 최대한 활용하는 방법

불행히도 GPU 리소스에도 한계가 있습니다. 그리고 엄밀히 말하면 커널 기능을 시작하기 전에 한계를 정의하고 부하를 분산할 때 이러한 한계를 고려하는 것이 좋습니다. 왜 중요 함?

비디오 카드에는 하나의 멀티프로세서가 실행할 수 있는 총 스레드 수, 한 블록의 최대 스레드 수, 한 프로세서의 최대 워프 ​​수, 다양한 메모리 유형에 대한 제한 등이 있습니다. 이 모든 정보는 해당 API를 통해 프로그래밍 방식으로 요청할 수 있으며 이전에는 SDK의 유틸리티를 사용하여 요청할 수 있습니다. (NVidia 장치용 deviceQuery 모듈, AMD 비디오 카드용 CLInfo 모듈).

일반 관행:

  • 스레드 블록/작업 그룹의 수는 스트림 프로세서 수의 배수여야 합니다.
  • 블록/작업 그룹 크기는 워프 크기의 배수여야 합니다.

동시에 각 프로세서에서 3-4개의 워프/웨이프론트가 동시에 회전하고 있으며 현명한 가이드는 최소 7개의 웨이프론트를 고려하여 진행하는 것이 좋습니다. 동시에 - 철에 대한 제한을 잊지 마십시오!

이러한 모든 세부 사항을 머릿속에 저장하면 금방 지루해집니다. 따라서 NVidia는 GPU 점유율을 계산하기 위해 예상치 못한 도구인 매크로로 가득 찬 엑셀(!) 계산기를 제공했습니다. 거기에서 SM의 최대 스레드 수, 레지스터 수 및 사용 가능한 공유(공유) 메모리 크기에 대한 정보를 입력할 수 있습니다. 스트림 프로세서, 그리고 사용된 함수 실행 매개변수 - 리소스 사용 효율성의 백분율을 제공합니다(모든 코어를 사용하기에 충분한 레지스터가 없다는 것을 깨닫고 머리를 찢습니다).

사용 정보:
http://docs.nvidia.com/cuda/cuda-c-best-practices-guide/#calculating-occupancy

GPU 및 메모리 작업

비디오 카드는 128비트 메모리 작업에 최적화되어 있습니다. 저것들. 이상적으로는 각 메모리 조작이 한 번에 4바이트 값 4개를 변경해야 합니다. 프로그래머의 주요 성가심은 GPU용 최신 컴파일러가 이러한 것들을 최적화할 수 없다는 것입니다. 이것은 함수 코드에서 바로 수행되어야 하며 평균적으로 성능 향상의 일부를 가져옵니다. 메모리 요청 빈도는 성능에 훨씬 더 큰 영향을 미칩니다.

문제는 다음과 같습니다. 각 요청은 128비트의 배수인 데이터 조각을 응답으로 반환합니다. 그리고 각 스레드는 그 중 1/4만 사용합니다(일반 4바이트 변수의 경우). 인접한 스레드가 메모리 셀에 순차적으로 위치한 데이터와 동시에 작동하면 총 메모리 액세스 횟수가 줄어듭니다. 이 현상을 읽기 및 쓰기 결합 작업( 통합 액세스 - 좋습니다! 읽기와 쓰기 모두) - 코드의 올바른 구성( 연속적인 메모리 청크에 대한 접근 - 나쁨!) 성능을 크게 향상시킬 수 있습니다. 한 메모리 행의 요소 내에서 커널을 구성할 때 - 기억 - 연속 액세스 - 열 요소로 작업하는 것은 더 이상 효율적이지 않습니다. 자세한 내용을 원하십니까? 나는 이 pdf를 좋아했다 - 또는 " 메모리 병합 기술 “.

"병목 현상"지명의 선두 위치는 다른 메모리 작업에 의해 점유됩니다. 호스트 메모리에서 GPU로 데이터 복사 . 복사는 어쨌든 발생하지 않지만 드라이버와 시스템이 특별히 할당한 메모리 영역에서 발생합니다. 데이터 복사 요청이 있을 때 시스템은 먼저 이 데이터를 복사한 다음 GPU에 업로드합니다. 데이터 전송 속도는 대역폭에 의해 제한됩니다. PCI 버스최신 비디오 카드가 호스트와 통신하는 데 사용되는 Express xN(여기서 N은 데이터 라인 수)입니다.

그러나 호스트에서 느린 메모리를 추가로 복사하는 것은 때때로 부당한 오버헤드입니다. 탈출구는 소위 고정된 메모리 - 특별히 표시된 메모리 영역으로 운영 체제가 어떠한 작업도 수행할 수 없습니다(예: 재량에 따라 스왑/이동하기 위해 언로드). 호스트에서 비디오 카드로의 데이터 전송은 운영 체제의 참여 없이 수행됩니다. DMA (직접 메모리 액세스).

마지막으로 메모리에 대해 조금 더 자세히 알아보겠습니다. 다중 프로세서의 공유 메모리는 일반적으로 32비트 워드(데이터)를 포함하는 메모리 뱅크의 형태로 구성됩니다. 뱅크 수는 전통적으로 GPU 세대마다 다릅니다. 16/32 각 스레드가 별도의 뱅크에서 데이터를 요청하면 모든 것이 정상입니다. 그렇지 않으면 하나의 뱅크에 대한 여러 읽기/쓰기 요청이 얻어지고 다음이 발생합니다. 충돌( 공유 메모리 뱅크 충돌). 이러한 충돌하는 호출은 직렬화되므로 병렬이 아닌 순차적으로 실행됩니다. 모든 스레드가 동일한 뱅크에 액세스하면 "브로드캐스트" 응답이 사용됩니다( 방송) 충돌이 없습니다. 접근 충돌에 효과적으로 대처할 수 있는 방법이 여러 가지 있는데, 마음에 들었습니다. 메모리 뱅크에 대한 액세스 충돌을 제거하기 위한 주요 기술에 대한 설명 – .

수학 연산을 더 빠르게 하는 방법은 무엇입니까? 기억:

  • 배정밀도 계산은 fp64 >> fp32로 작업 부하가 큽니다.
  • 코드에서 3.13 형식의 상수는 3.14f를 명시적으로 지정하지 않으면 기본적으로 fp64로 해석됩니다.
  • 수학을 최적화하기 위해 가이드를 참조하는 것이 불필요하지 않습니다. 컴파일러에 대한 플래그가 있습니까?
  • 공급업체는 성능을 달성하기 위해 장치 기능을 활용하는 기능을 SDK에 포함합니다(종종 이식성을 희생함).

CUDA 개발자가 개념에 세심한 주의를 기울이는 것이 합리적입니다. 쿠다 스트림,하나의 장치에서 여러 핵심 기능을 한 번에 실행하거나 기능 실행 중에 호스트에서 장치로 데이터의 비동기식 복사를 결합할 수 있습니다. OpenCL은 아직 이러한 기능을 제공하지 않습니다 🙁

정크 프로파일링:

NVifia Visual Profiler는 CUDA 및 OpenCL 커널을 모두 분석하는 흥미로운 유틸리티입니다.

추신 더 긴 최적화 가이드로 모든 종류의 인터넷 검색을 추천할 수 있습니다. 모범 사례 가이드 OpenCL 및 CUDA용.

  • ,

GPU의 병렬 컴퓨팅에 대해 말하면, 우리는 우리가 살고 있는 시간을 기억해야 합니다. 오늘날은 세상의 모든 것이 너무 가속화되어 시간이 어떻게 흘러가는지 모르고 시간을 추적하지 못하는 시간입니다. 우리가 하는 모든 일은 정보 처리의 높은 정확도와 속도로 연결됩니다. 이러한 상황에서 우리는 우리가 가지고 있는 모든 정보를 처리하고 이를 데이터로 변환하기 위한 도구가 확실히 필요합니다. 게다가 그러한 작업에 대해 말하면 이러한 작업을 기억해야 합니다. 대기업이나 대기업뿐만 아니라 일반 사용자도 이제 이러한 문제를 해결해야 하며, 집에서 첨단 기술과 관련된 중요한 작업을 해결해야 합니다. 개인용 컴퓨터! NVIDIA CUDA의 출현은 놀라운 것이 아니라 오히려 정당화되었습니다. 이전보다 PC에서 훨씬 더 많은 시간이 소요되는 작업을 처리해야 하기 때문입니다. 이전에는 매우 오랜 시간이 걸렸던 작업이 이제 각각 몇 분 정도 소요됩니다. 이는 전 세계의 전반적인 그림에 영향을 미칠 것입니다!

GPU 컴퓨팅이란

GPU 컴퓨팅은 GPU를 사용하여 기술, 과학 및 일상적인 작업을 계산하는 것입니다. GPU에서의 컴퓨팅은 CPU와 GPU를 이질적인 선택으로 사용하는 것을 포함합니다. 이로 인해 작업이 병렬화되어 정보 처리가 빨라지고 작업을 완료하는 데 걸리는 시간이 단축되며 시스템의 생산성이 향상되고 이전보다 더 많은 작업을 동시에 처리할 수 있습니다. 그러나 이러한 성공을 달성하려면 하드웨어 지원만으로는 충분하지 않습니다. 이 경우 응용 프로그램에서 가장 시간이 많이 걸리는 계산을 GPU로 전송할 수 있도록 소프트웨어 지원도 필요합니다.

쿠다란 무엇인가

CUDA는 8세대 및 이전 GeForce 가속기의 그래픽 프로세서와 NVIDIA의 해당 Quadro 및 Tesla 카드에서 실행되는 단순화된 C 언어로 알고리즘을 프로그래밍하는 기술입니다. CUDA를 사용하면 C 프로그램의 텍스트에 특수 기능을 포함할 수 있습니다. 이러한 기능은 단순화된 C 프로그래밍 언어로 작성되고 GPU에서 실행됩니다. CUDA SDK의 초기 버전은 2007년 2월 15일에 출시되었습니다. 이 언어로 코드를 성공적으로 번역하기 위해 CUDA SDK에는 자체 C 컴파일러가 포함되어 있습니다. 명령줄 NVIDIA의 nvcc. nvcc 컴파일러는 다음을 기반으로 합니다. 오픈 컴파일러 Open64는 호스트 코드(메인, 제어 코드) 및 장치 코드(하드웨어 코드)(확장자가 .cu인 파일)를 모든 프로그래밍 환경에서 최종 프로그램 또는 라이브러리를 빌드하는 데 적합한 개체 파일로 변환하도록 설계되었습니다. , 마이크로소프트 비주얼 스튜디오에서.

기술 역량

  1. GPU 애플리케이션의 병렬 개발을 위한 C 표준 언어.
  2. 빠른 푸리에 변환 및 선형 대수 프로그램의 기본 패키지를 위한 기성품 수치 분석 라이브러리.
  3. GPU와 CPU 간의 빠른 데이터 전송으로 컴퓨팅을 위한 전용 CUDA 드라이버.
  4. CUDA 드라이버가 OpenGL 및 DirectX 그래픽 드라이버와 상호 작용할 수 있는 기능.
  5. 수술실 지원 리눅스 시스템 32/64비트, Windows XP 32/64비트 및 MacOS.

기술 이점

  1. CUDA API(응용 프로그래밍 인터페이스)는 몇 가지 제한 사항이 있는 표준 C 프로그래밍 언어를 기반으로 합니다. 이것은 CUDA 아키텍처를 배우는 과정을 단순화하고 매끄럽게 합니다.
  2. 스레드 간 16KB 공유 메모리는 일반 텍스처에서 가져올 때보다 대역폭이 더 넓은 사용자 구성 캐시에 사용할 수 있습니다.
  3. CPU 메모리와 비디오 메모리 간의 보다 효율적인 트랜잭션.
  4. 정수 및 비트 연산에 대한 전체 하드웨어 지원.

기술 적용의 예

크락

이 프로그램의 가장 어려운 부분은 팅크입니다. 이 프로그램에는 콘솔 인터페이스가 있지만 프로그램 자체와 함께 제공되는 지침 덕분에 사용할 수 있습니다. 다음은 짧은 지시프로그램 설정을 위해. 우리는 프로그램의 성능을 테스트하고 NVIDIA CUDA를 사용하지 않는 다른 유사한 프로그램과 비교할 것입니다. 이 경우 잘 알려진 프로그램인 "Advanced Archive Password Recovery"입니다.

다운로드한 cRark 아카이브에서 crark.exe , crark-hp.exe 및 password.def 세 파일만 필요합니다. Сrark.exe는 아카이브 내부에 암호화된 파일이 없는 RAR 3.0 암호 크래커입니다(즉, 아카이브를 열면 이름이 표시되지만 암호 없이 아카이브의 압축을 풀 수 없음).

Сrark-hp.exe는 전체 아카이브를 암호화하는 명령줄 RAR 3.0 암호 크래킹 유틸리티입니다(즉, 아카이브를 열 때 이름이나 아카이브 자체가 표시되지 않으며 아카이브 없이 아카이브 압축을 풀 수 없습니다. 비밀번호).

Password.def는 내용이 거의 없는 이름이 변경된 텍스트 파일입니다(예: 첫 번째 줄: ## 두 번째 줄: ?* , 이 경우 모든 문자를 사용하여 암호가 해독됨). Password.def는 cRark 프로그램의 머리입니다. 파일에는 암호(또는 crark.exe가 작업에서 사용할 문자 영역)를 여는 규칙이 포함되어 있습니다. 이 문자를 선택하는 옵션에 대한 자세한 내용은 cRark 프로그램 작성자가 다운로드한 사이트인 russian.def를 열어 얻은 텍스트 파일에 기록되어 있습니다.

훈련

비디오 카드가 CUDA 1.1 가속 수준을 지원하는 GPU를 기반으로 하는 경우에만 프로그램이 작동한다고 즉시 말해야 합니다. 따라서 GeForce 8800 GTX와 같은 G80 칩을 기반으로 하는 일련의 비디오 카드는 CUDA 1.0 가속에 대한 하드웨어 지원이 있기 때문에 문제의 여지가 없습니다. CUDA를 사용하여 프로그램은 버전 3.0 이상의 RAR 아카이브에 대한 암호만 선택합니다. 모든 CUDA 관련 소프트웨어를 설치해야 합니다.

모든 폴더(예: C: 드라이브)를 만들고 이름을 "3.2"와 같이 지정합니다. crark.exe , crark-hp.exe 및 password.def 및 암호로 보호/암호화된 RAR 아카이브 파일을 여기에 넣습니다.

다음으로 Windows 명령줄 콘솔을 시작하고 그 안에 생성된 폴더로 이동해야 합니다. Windows Vista 및 7에서는 "시작" 메뉴를 호출하고 검색 필드에 "cmd.exe"를 입력해야 합니다. Windows XP에서는 "시작" 메뉴에서 "실행" 대화 상자를 먼저 호출하고 "cmd"를 입력해야 합니다. .exe"가 있습니다. 콘솔을 연 후 cd C:\folder\ , 이 경우 cd C:\3.2 와 같은 명령을 입력합니다.

에서 모집 텍스트 에디터암호화되지 않은 파일이 있는 암호로 보호된 RAR 아카이브의 암호를 추측하기 위해 두 줄(텍스트를 cRark이 있는 폴더에 .bat 파일로 저장할 수도 있음):

에코 꺼짐;
cmd /K crark(아카이브 이름).rar

암호로 보호되고 암호화된 RAR 아카이브의 암호를 추측하려면:

에코 꺼짐;
cmd /K crark-hp(아카이브 이름).rar

2줄 복사 텍스트 파일콘솔에 입력하고 Enter 키를 누릅니다(또는 .bat 파일 실행).

결과

암호 해독 프로세스는 그림에 나와 있습니다.

CUDA를 사용하여 cRark에서 선택 속도는 1625 암호/초였습니다. 1분 36초 동안 "q)$"라는 3자의 암호가 추측되었습니다. 비교를 위해 내 듀얼 코어 Athlon 3000+ 프로세서의 Advanced Archive Password Recovery의 무차별 암호 대입은 최대 초당 50개의 암호이고 무차별 암호 대입에는 5시간이 걸립니다. 즉, GeForce 9800 GTX+ 비디오 카드를 사용하여 cRark에서 무차별 대입으로 RAR 아카이브를 선택하는 것이 CPU보다 30배 빠릅니다.

Intel 프로세서, 시스템 버스 주파수(FSB 1600MHz)가 높은 우수한 마더보드를 사용하는 사용자의 경우 CPU 속도와 무차별 대입이 더 높을 것입니다. 그리고 쿼드 코어 프로세서와 GeForce 280 GTX 수준의 한 쌍의 비디오 카드가 있는 경우 암호 무차별 암호 대입 공격의 성능이 때때로 가속화됩니다. 예를 들어 요약하자면 5시간이 아닌 2분 만에 CUDA 기술을 사용하여 이 문제를 해결했다고 할 수 있습니다. 이는 이 기술의 높은 잠재력을 나타냅니다!

결론

오늘날 병렬 컴퓨팅 CUDA를 위한 기술을 고려하면서 우리는 암호 복구 프로그램의 예를 사용하여 이 기술의 개발에 대한 모든 능력과 엄청난 잠재력을 분명히 보았습니다. RAR 아카이브. 나는 이 기술의 전망에 대해 말해야 한다. 이 기술과학 작업이든 비디오 처리와 관련된 작업이든 빠르고 정확한 계산이 필요한 경제 작업이든 사용하기로 결정한 모든 사람의 삶에서 확실히 자리를 찾을 것입니다. 이 모든 것은 노동의 불가피한 증가로 이어질 것입니다. 무시할 수 없는 생산성 . 현재까지 "가정용 슈퍼컴퓨터"라는 문구는 이미 사전에 들어가기 시작했습니다. 그러한 물체를 현실로 번역하기 위해 모든 가정에는 이미 CUDA라는 도구가 있다는 것은 절대적으로 분명합니다. G80 칩 기반 카드 출시(2006) 이후, 큰 금액모든 가정에서 슈퍼컴퓨팅의 꿈을 현실로 만들 수 있는 CUDA 기술을 지원하는 NVIDIA 기반 가속기. NVIDIA는 CUDA 기술을 홍보함으로써 이미 많은 사람들이 구매한 장비에 추가 기능을 제공하는 형태로 고객의 눈에 신뢰성을 높입니다. 머지 않아 CUDA가 매우 빠르게 발전하고 사용자가 GPU에서 병렬 컴퓨팅의 모든 가능성을 최대한 활용할 수 있을 것이라고 믿는 것만 남아 있습니다.