В конце 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. В качестве примера можно привести организацию работы с памятью: по всей видимости, на уровне низкоуровневых операций очень много нюансов, приводящих к некорректному поведению библиотеки. Работы в этом направлении, а также в части достижения требуемой производительности еще продолжаются.

Читайте также:

Разработка кроссплатформенного ядра геометрического моделирования

Комментарии (1)


  1. OpenA
    02.11.2022 12:32
    +1

    Документация по компилятору находится в папке самого компилятора
    /opt/mcst/lcc-1.2X.e2k-cross/doc ~ например

    Там же лежит и man, да и lcc --help раньше по крайней мере все что есть выкатывал.

    указана совместимость с GCC лишь для старой версии компилятора

    lcc --version должно показывать какой версии GCC оно соответствует. Совместимость естественно реализована примерно как у clang: опции принимает, но ругается своими ошибками в неожиданных местах. В любом случае там лишние вроде выключаются флагами.