- PVSM.RU - https://www.pvsm.ru -
Как известно, использование виртуальных машин, работа которых строится на программной интерпретации кода, позволяет создавать универсальные приложения, выполняемые на различных аппаратных платформах без рекомпиляции. Технология EFI Byte Code [1] является типичным примером успешного применения данного подхода. Но при всех его преимуществах есть очевидный недостаток – программно реализованный процессор существенно медленнее аппаратного. В предлагаемой статье рассматривается метод, позволяющий нивелировать падение производительности EBC-программ на примере операций заполнения блока памяти константой и копирования содержимого блока памяти. Причем, об использовании «вставок» нативного кода центрального процессора речь не идет, поскольку это дискредитирует саму идею кроссплатформенности [2].
Итак, представим, что нашему приложению необходимо заполнять заданной константой, заданные области памяти, а также выполнять копирование блоков. Причем массивы достаточно большого размера и производительность данной операции критична для производительности приложения в целом. Использование EBC-инструкций для обработки блоков приведет к потере производительности, а «вставки» нативного кода означают потерю кроссплатформенности. Как быть?
Разработчики спецификации UEFI предусмотрели изящное решение для проблем такого типа. В наборе сервисных функций EFI Boot Services предусмотрены процедуры для заполнения блока памяти константой SetMem() и копирования блока памяти CopyMem(). Напомним, сервисные процедуры UEFI API делятся на EFI Boot Services и EFI Runtime Services. Первые доступны только на фазе загрузки ОС, вторые – в течение всего времени работы ОС.
Рис 1. Описание параметров функции SetMem() в документе UEFI Specification version 2.4 Errata A.
Buffer – базовый адрес блока;
Size – размер блока;
Value – данные для заполнения блока.
Функция заполняет байтовой константой Value блок памяти, адрес которого равен значению Buffer, размер в байтах равен значению Size.
Рис 2. Описание параметров функции CopyMem() в документе UEFI Specification version 2.4 Errata A
Destination – базовый адрес блока-получателя;
Source – базовый адрес блока-источника;
Length – длина для операции пересылки, в байтах.
Функция копирует блок-источник размером Length, расположенный по адресу Source, в блок-получатель, расположенный по адресу Destination.
На Рис.3 приведен листинг EBC-программы, заполняющей константой 11h блок, размером 32 байта. Рассмотрим ее выполнение. В регистр R7 записывается базовый адрес блока, R6 – длина блока, R5 – данные для записи. После этого создается стековый фрейм, используемый для передачи параметров вызываемой подпрограмме. Затем, из таблицы EFI System Table читается адрес дочерней таблицы EFI Boot Services Table, в которой, в свою очередь под номером 42 находится указатель для вызова функции SetMem(). Для шлюзования между EBC-программой и вызываемой процедурой UEFI firmware используется инструкция CALL32EXA. После того, как подпрограмма отработала, стековый фрейм ликвидируется.
В этом и следующем примерах, _Primary_Memory_Base и _EFI_Table это смещения, используемые для адресации переменных, хранящих соответственно базовый адрес блока памяти, используемого программой и базовый адрес корневой системной таблицы EFI System Table, передаваемый приложению при старте.
Вспомним одну особенность построения системных таблиц UEFI, существенную для обеспечения кроссплатформенности. 32-битные реализации UEFI используют указатели размером 4 байта, 64 битные – размером 8 байт. Поле заголовка таблицы всегда имеет размер 24 байта. Поэтому, инструкции, адресующие системные таблицы UEFI оперируют двумя слагаемыми при вычислении адреса: номер указателя (entry) и размер заголовка (header size). Это позволяет виртуальной машине EBC корректно вычислить адрес требуемого элемента, независимо от нативной разрядности процессора, определяющей размер элементов.
Рис 3. Пример процедуры заполнения блока константой с использованием функции SetMem(). Используются инструкции ассемблера EBC
Рис 4. Результат работы процедуры заполнения блока константой с использованием функции SetMem(). Для просмотра используется Intel EBC Debugger. В этом примере базовый адрес визуализируемого блока 6C40000h, длина 80h=128 байт. Константой 11h заполнен блок размером 32 байта
На Рис.5 приведен листинг EBC-программы, выполняющей копирование блока размером 32 байта. Рассмотрим ее выполнение. В регистр R7 записывается базовый адрес блока-источника, R6 – базовый адрес блока-получателя, R5 – длина блоков. После этого создается стековый фрейм, используемый для передачи параметров вызываемой подпрограмме. Затем, из таблицы EFI System Table читается адрес дочерней таблицы EFI Boot Services Table, в которой, в свою очередь под номером 41 находится указатель для вызова функции CopyMem(). Для шлюзования между EBC-программой и вызываемой процедурой UEFI firmware используется инструкция CALL32EXA. После того, как подпрограмма отработала, стековый фрейм ликвидируется.
Рис 5. Пример процедуры копирования блока с использованием функции CopyMem(). Используются инструкции ассемблера EBC
Рис 6. Результат работы процедуры копирования блока с использованием функции CopyMem(). Для просмотра используется Intel EBC Debugger. В этом примере базовый адрес визуализируемого блока 6C40000h, длина 80h=128 байт. Блок-источник, расположенный по адресам 6C40000h-6C4001Fh, скопирован в блок-получатель по адресам 6C40030h-6C4004Fh
Реализация в составе UEFI firmware, функций, связанных с примитивной обработкой больших массивов, теоретически, позволяет оптимизировать выполнение этих операций под особенности конкретной платформы. Существенное повышение производительности может быть достигнуто с использованием 128 или 256-битных SSE-инструкций центрального процессора x86, применением различных DMA-сопроцессоров, а также аппаратной реализации средствами контроллера памяти. Насколько эффективно разработчики платформ задействуют данный потенциал – покажут наши дальнейшие исследования, но даже при использовании процедурами UEFI firmware классических 32-битных x86-инструкций, EBC-приложение, не теряя кроссплатформенности и выполняясь на программном процессоре, получает в свое распоряжение производительность аппаратного процессора.
Автор: icbook
Источник [3]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/zhelezo/56090
Ссылки в тексте:
[1] Технология EFI Byte Code: http://habrahabr.ru/post/201954/
[2] кроссплатформенности: http://habrahabr.ru/post/212363/
[3] Источник: http://habrahabr.ru/post/214119/
Нажмите здесь для печати.