Сравнение эффективности компиляторов под Эльбрус на примере решета Эратосфена

На Хабре уже тестирование Эльбрусов на разных языках программирования (например, здесь). И данный обзор стоит рассматривать как дополнение, с ещё одним тестом, новыми версиями компиляторов и новыми участниками (Rust, С++). Так же обзор сделан с упором на тест возможностей именно компиляторов и настройки оптимизации.

Тестовые стенды:

x86:

Софт:

Ubuntu 22.04.

Java: OpenJDK Runtime Environment (build 11.0.25+9-post-Ubuntu-1ubuntu122.04).

Rust: rustc / cargo v. 1.83.0; LLVM version: 19.1.1.

C++: GCC v11.4.0; LLVM version 19.1.5.

e2k:

Софт:

Java: OpenJDK Runtime Environment (build 11.0.15-Unipro+0-adhoc.root.openjdk11–11.0.15).

Rust: rustc / cargo v. 1.57.0.

C++: GCC v9.3.0 compatible; LLVM version 13.0.1.

Испытуемые: Java, Rust, C++(GCC, LLC).

Тест.

В качестве теста выступает решето Эратосфена в блочном варианте. Один поток. На трёх языках реализовано максимально идентично. Программа в консольном варианте. Есть возможность повторного расчёта.

Методика тестирования.

Выполняем два запуска по пять прогонов поиска простых чисел в диапазоне 0 — 5×108. Первый прогон разогревочный и в расчёт не идёт. Для Java прогревочный проход обязателен. И, как показала практика, на C++ и Rust первый прогон тоже чуть медленнее. По оставшимся результатам двух прогонов вычисляется средний показатель.

Результаты тестов.

В сравнении gcc и llc, gcc оказался чуть эффективнее, но разница очень маленькая, меньше 1%. Поэтому ниже в тестах будут фигурировать значения llc с обозначением gcc/llc. Значения указаны в миллисекундах.

Некоторые неожиданности.

Ожидалось, что исполняемые файлы, полученные на одной x86-машине должны работать на другой x86-машине. Но файлы, скомпилированные GCC/LLC на AMD FX с настройкой оптимизации выше чем O0, на Intel Celeron (Haswell) выпадали с ошибкой:»Недопустимая инструкция (образ памяти сброшен на диск)». Однако с Rust таких проблем не наблюдалось. И так же всё, что скомпилировано на Intel, работало на AMD FX. При этом, независимо от того, на какой машине был получен исполняемый файл, результаты тестов совпадали.

gcc
O0

gcc/llc O2

gcc/llc O3

gcc/llc O4

Rust
O2

Rust
O3

Java

Elbrus 8C @ 1.2Ghz

45712

4694

3912

3830

4941

5033

19357

AMD FX @ 3.5Ghz

7743

2373

2208

2205

1818

1918

4635

Cel G1820 @ 2.7Ghz

7508

1648

1523

1543

1183

1213

5123

Жирным выделены результаты самых удачных настроек компиляции для каждой машины.

Сразу бросается в глаза разница между gcc O0 и gcc/llc O2 на Эльбрусе. Такова плата за запуск неоптимизированных программ на e2k.

В отличие от x86, для Эльбруса оптимизация O4 даёт профит.

43e0c8642bfae5fba73cdf1d20b52272.png

А вот для Rust везде лучший результат показала оптимизация O2.

И так, лучшие настройки оптимизации для данного теста на платформах:

  • x86: Rust — O2, C++ — O3.

  • e2k: Rust — O2, C++ — O4.

08d11f27532274e94fe9623895289629.pnge0f5f2c20458491a7a8c8a070a06d893.png

P.S.

Не являюсь специалистом по Rust и C++. Код достаточно простой и там вряд ли будут серьёзные недочёты. Но мог недоработать в плане настроек компиляции.
Благодарю компанию МЦСТ за возможность ознакомления с ЦП семейства Эльбрус!

Ресурсы:

Исходник Java, исходник Rust, исходник C++

© Habrahabr.ru