Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
В конце 2021 года мы инициировали процесс портирования геометрического ядра C3D на отечественную платформу «Эльбрус». В этой заметке мы хотим рассказать об основных этапах этого процесса.
«Эльбрус» — это программно-аппаратная платформа, которая разрабатывается компанией МЦСТ. Процессоры данной модели используют набор команд типа RISC (Reduced Instruction Set Computer) и имеют собственную архитектуру E2K. Последняя относится к типу VLIW, то есть имеет длинную машинную команду.
Стоит отметить, что большинство современных процессоров основано на наборе команд типа CISC (Complicated Instruction Set Computer) и имеет архитектуры x86_64 или arm. Из сказанного выше следует, что архитектура E2K отличается рядом особенностей по сравнению с другими архитектурами, что создает определённые сложности при портировании. Поэтому ниже мы перечислим некоторые из этих сложностей.
Техника кросс-компиляции
Впервые мы столкнулись с техникой так называемой кросс-компиляции в связи с отсутствием у нас собственного компьютера на базе «Эльбрус». В результате возникло требование к собираемой на базе «Эльбрус Линукс» с архитектурой x86_64 библиотеки ядра: она должна работать на машинах с архитектурой E2K. Поставленную задачу можно было решить путем использования кросс-компиляции: на машине-хосте с архитектурой x86_64 устанавливается окружение целевой машины с архитектурой E2K, после чего с помощью специального кросс-компилятора собирается библиотека с системными зависимостями целевой архитектуры. С задачей мы справились и теперь планируем использовать полученные навыки при сборке ядра на других дистрибутивах Linux.
Собственный компилятор
«Эльбрус» использует собственный системный компилятор LCC. Несмотря на уверения разработчиков платформы, что командный интерфейс компилятора совпадает с интерфейсом GCC, полная совместимость все равно отсутствует. Кроме того, LCC не может «угнаться» за поддержкой новых стандартов C++ и поддерживает только c++14. Еще одна проблема заключается в том, что нет четкого описания поддерживаемых особенностей. Например, по заданной версии GCC можно определить, какие особенности языка поддерживаются, но в документации (руководстве по эффективному программированию на платформе «Эльбрус») указана совместимость с GCC лишь для старой версии компилятора, а своего полного списка «фич» у LCC нет. Нельзя не отметить и ограничения (описанные в документации) при использовании прагм или встроенных команд GCC.
Отдельно обратим внимание на проблему многопоточности, связанную с неполной поддержкой платформой E2K стандарта OpenMP. Так как компилятор LCC понимает далеко не все его директивы, отдельные участки кода пришлось менять для обеспечения корректной компиляции. Например, после num_threads
не может идти вычисляемое выражение. Поэтому блоки типа
#pragma omp parallel num_threads ((int)viewCount) if (useParallel)
пришлось заменить на
int vc = (int)viewCount;
#pragma omp parallel num_threads (vc) if (useParallel)
Кроме того, к примеру, не поддерживается директива #pragma omp for
и т.д.
Поведение компилятора значительно отличается от GCC, причем логика работы не всегда понятна. В логе компиляции можно увидеть неожиданные уведомления, которые не возникают в других компиляторах. При линковке мы также получали необъяснимые ошибки. Одна из них, например, заключалась в «ругани» на отсутствие символов, которые в принципе не присутствовали и не должны были присутствовать в коде. В конечном итоге, после необходимой адаптации исходных текстов нам удалось собрать и запустить библиотеку C3D на «Эльбрус Линукс» с архитектурой E2K.
Работоспособность ядра под «Эльбрус»
Следующий этап, к которому мы приступили, — проверка элементарной работоспособности ядра. Для начала нам было необходимо обеспечить работу базовой функциональности по построению геометрических объектов. И здесь как раз проявились основные сложности, связанные с особенностями архитектуры E2K. В качестве примера можно привести организацию работы с памятью: по всей видимости, на уровне низкоуровневых операций очень много нюансов, приводящих к некорректному поведению библиотеки. Работы в этом направлении, а также в части достижения требуемой производительности еще продолжаются.
Читайте также:
Разработка кроссплатформенного ядра геометрического моделирования