Pull to refresh
0

Intel® Graphics Technology. Часть I: почти Gran Turismo

Reading time 4 min
Views 18K


В посте про «новшества» Parallel Studio XE 2015 я обещал написать про интересную технологию от Intel — Graphics Technology. Собственно, это я и собираюсь сделать сейчас. Суть Intel Graphics Technology заключается в использовании интегрированного в процессор графического ядра для выполнения вычислений на нем. Это оффлоад (offload) на графику, что, естественно, дает прирост производительности. Неужели интегрированная графика настолько мощна, что этот прирост будет действительно велик?
Давайте посмотрим на семейство новых графических ядер GT1, GT2 и GT3/GT3e, интегрированных в процессоры 4-го поколения Intel Core.

Да, графика была и в 3-ем поколении, но это уже «дела минувших дней». Ядро GT1 имеет минимальную производительность, а GT3 — максимальную:
HD (GT) HD 4200,
HD 4400,
HD 4600 (GT2)
HD 5000,
Iris 5100 (GT3),
Iris Pro 5200 (GT3e)
API DirectX 11.1, DirectX Shader Model 5.0, OpenGL 4.2, OpenCL 1.2
Число
исполнительных
блоков (Execution Unit)
10 20 40
Число FP операций
за такт
160 320 640
Число потоков на
исполнительном
устройстве / всего
7 / 70 7 / 140 7 / 280
L3 кэш
256 512 1024
GPU состоит из слоёв (slice). Такая структура упрощает дизайн и производство, а возможные конфигурации содержат ½, 1 и 2 слоя (GT1, GT2 и GT3 соответственно):

То есть для случая с GT1 всё будет практически так же, только «слой» нужно разрезать пополам по горизонтали. Мы не будем мелочиться, и остановимся на возможностях графики GT3e, как наиболее продвинутого примера. Итак, имеем 40 исполнительных блоков по 7 потоков на каждый блок. Итого у нас имеется до 280 потоков! Неплохая прибавка мощности для «мотора» нашей системы!
При этом каждому потоку доступно по 4 KB в регистровом файле (GRF — General Register File) – наиболее быстрой из доступной для графики памяти для хранения локальных данных. Общий размер файла составляет 1120 KB.
Вообще, модель памяти представляет большой интерес и схематично может быть представлена так:

Кроме регистров, графике доступен свой L3 кэш (256 KB на каждые ½ «слоя»), а также LLC (Last Level Cache), который является L3 процессорным кэшем и, таким образом, общим для CPU и GPU. С точки зрения вычислений на GPU, кэшей L1 и L2 нет. Только в самой мощной конфигурации GT3e доступно ещё 128 MB кэша eDRAM. Он находится в одном корпусе с процессорным компонентом, но не является частью кристалла Haswell, и играет важную роль в увеличении производительности встроенной графики, почти ликвидируя зависимость от оперативной памяти компьютера (DRAM), часть которой так же может быть использована в качестве видеопамяти.

Далеко не все версии процессоров имеют ту самую интегрированную графику. Серверные модели предпочитают иметь значительно больше вычислительных ядер вместо графики, поэтому случаи, в которых возможно применение Graphics Technology, существенно сужаются. Я наконец дождался лэптопа с Haswell’ом и встроенной в процессор графикой Intel HD Graphics 4400, а, значит, можно поиграться с Intel Graphics Technology, которая поддерживается на 64 битных Linux системах, а так же на 32 и 64 битных Windows системах.

Собственно, по требованию к «железу» всё понятно – без него про вычисления на графическом ядре говорить бессмысленно. В документации (да, да… мне даже пришлось её почитать, потому что сразу всё не заработало) сказано, что всё должно работать с этими моделями:
  • Intel Xeon Processor E3-1285 v3 and E3-1285L v3 (Intel C226 Chipset) с Intel HD Graphics P4700
  • 4е поколение Intel Core процессоров с Intel Iris Pro Graphics, Intel Iris Graphics или Intel HD Graphics 4200+ Series
  • 3е поколение Intel Core процессоров с Intel HD Graphics 4000/2500

«Железка подходит, компилятор с поддержкой GT поставлен. Все должно полететь!» — подумал я, и принялся собирать сэмплы, поставляемые с компилятором для Graphics Technology.

С точки зрения кода, ничего экстраординарного я не заметил. Да, появились какие-то прагмы перед циклами cilk_for, вроде таких:

void vector_add(float *a, float *b, float *c){
#pragma offload target(gfx) pin(a, b, c:length(N))
cilk_for(int i = 0; i < N; i++)
        c[i] = a[i] + b[i];
return;
}

Об этом мы поговорим подробно в следующем посте, а пока попробуем собрать сэмпл с опцией /Qoffload. Вроде бы всё скомпилировалось, но ошибка о том, что линкер (ld.exe) не может быть найден, меня немного приостановила. Оказалось, я упустил один важный момент и не всё так тривиально. Пришлось покопаться в документации.

Оказалось, что программный стек для выполнения приложения с оффлоадом на интегрированную графику выглядит так:

Компилятор не умеет генерировать код, который сразу может выполняться на графике. Он создает IR (Intermediate Representation) код под vISA (Virtual Instruction Set Architecture) архитектуру. А тот в свою очередь может выполняться (конвертироваться в рантайме) на графике с помощью JIT’тера, поставляемого в установочном пакете с драйверами для Intel HD Graphics.

При компиляции нашего кода с использование оффлоада для Graphics Technology, генерится объектник, в который «вшита» часть, выполняющаяся на графическом ядре. Этот общий файл называется fat. При линковке вот таких вот «толстячков» (fat объектников), код, выполняющийся на графике, будет в секции, встроенной в бинарник на хосте, называемой .gfxobj (для случая Windows).
Вот тут то становится понятно, почему не находился линкер. У компилятора Intel нет и не было своего линкера, причем что на Linux, что на Windows. А здесь в один файл нужно «зашить» объектники в разных форматах. Простой линкер от Microsoft делать этого не умеет, поэтому нужно поставить специальную версию binutils (2.24.51.20131210), доступную здесь, а потом и прописать пусть к тому самому ld.exe (в моем случае C:\Program Files (x86)\Binutils for MinGW (64 bit)\bin) в PATH.
После установки всего необходимого, я в итоге собрал тестовый проект на Windows и получил следующее:
dumpbin matmult.obj
Microsoft (R) COFF/PE Dumper Version 12.00.30723.0
Copyright (C) Microsoft Corporation.  All rights reserved.
Dump of file matmult.obj
File Type: COFF OBJECT
  Summary
          48 .CRT$XCU
          2C .bss
         5D0 .data
        111C .data1
       148F4 .debug$S
          68 .debug$T
         32F .drectve
       33CF8 .gfxobj
         6B5 .itt_notify_tab
         8D0 .pdata
         5A8 .rdata
        AD10 .text
         D50 .xdata

Нужный объектник для выполнения на графике можно извлечь из fat объектника с помощью специального инструмента (offload_extract). Если в нашей консоли выставлено окружение для запуска компилятора Intel, сделать это весьма просто:
offload_extract matmult.obj

В результате в папочке можно найти отдельный объектник с приставкой GFX в конце, в моем случае — matmultGFX.o. Он, кстати, уже ни разу не в PE формат, а в ELF’е.

Кстати, если оффлоад невозможен и графическое ядро недоступно во время запуска приложения, выполнение происходит на хосте (CPU). Это достигается с помощью средств компилятора и оффлоад рантайма.
С тем, как всё должно работать мы разобрались. Дальше будем говорить о том, что доступно разработчику и как написать код, который в итоге будет работать на графике.
Информации оказалось так много, что в рамки одного поста всё никак не помещается, поэтому, как говорится, «продолжение следует…».
Tags:
Hubs:
+16
Comments 18
Comments Comments 18

Articles

Information

Website
www.intel.ru
Registered
Founded
Employees
5,001–10,000 employees
Location
США
Representative
Анастасия Казантаева