Недавно я получил плату NVIDIA Jetson Xavier NX, чтобы просмотреть и написать несколько сообщений. Первый - это неофициальное руководство по обновлению Ubuntu 18.04 до последней версии Ubuntu Focal (20.04).

Здесь я проведу несколько тестов и сравню производительность Jetson NX и других SBC. Некоторое время назад я тестировал некоторые платы ARM, сравнивая их производительность на Java и других рабочих нагрузках. Здесь я сделаю аналогичный подход и добавлю несколько тестов и сравнений с графическим процессором и энергопотреблением.

Конечно, диапазон цен сильно варьируется: от 79 долларов за Odroid N2 и RockPro64 до 399 долларов за Xavier NX, мы не можем ожидать аналогичной производительности или функций. Все платы были настроены с использованием Debian или Ubuntu, и графический интерфейс не был включен.

Чтобы измерить использование CPU и GPU, я установил jtop из репозитория jetson-stats. Это утилита, похожая на htop, но получающая статистику NVIDIA. Приложение можно установить с sudo -H pip install -U jetson-stats и запустить с sudo jtop.

Заявление об ограничении ответственности: эти тесты и тесты производительности не являются научными и подтверждены строгими лабораторными стандартами. Они были сделаны в моей домашней лаборатории с использованием инструментов и оборудования с открытым исходным кодом, доступных в отмеченном. Кроме того, тесты, которые я использовал, никоим образом не являются исчерпывающими для всей доступной рабочей нагрузки.

Краткие характеристики платы

NVIDIA Jetson Xavier NX

  • ЦП: 6-ядерный 64-разрядный процессор Carmel Arm, 6 МБ L2 + 4 МБ L3.
  • Графический процессор: NVIDIA Volta с 384 ядрами NVIDIA CUDA и 48 тензорными ядрами, а также 2x NVDLA.
  • 8 ГБ 128-битной оперативной памяти LPDDR4x
  • Гигабитный Ethernet

HardKernel Odroid N2

  • Amlogic S922X (4x Cortex-A73 с частотой 1,8 ГГц, 2x Cortex-A53 с частотой 1,9 ГГц); 12 нм fab; Графический процессор Mali-G52 с 6 модулями EE по 846 МГц.
  • 4 ГБ оперативной памяти DDR4.
  • Гигабитный Ethernet

Pine64 RockPro64

  • Rockchip RK3399 Hexa-Core (два ядра ARM Cortex A72 и четыре ядра ARM Cortex A53), 64-разрядный процессор и четырехъядерный графический процессор MALI T-860.
  • 4 ГБ оперативной памяти LPDDR4.
  • PCIe x4.
  • Гигабитный Ethernet

Используемые контрольные показатели:

Тесты ЦП

7zip

Я использую тест 7zip в качестве основы для большинства плат, так как он показывает чистую производительность процессора и является хорошим сравнением между платами.

NVIDIA Jetson Xavier NX

❯ 7z b
7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,6 CPUs LE)
LE
CPU Freq: - 64000000 64000000 - 128000000 256000000 512000000 - 2048000000
RAM size:    7763 MB,  # CPU hardware threads:   6
RAM usage:   1323 MB,  # Benchmark threads:      6
Compressing  |                  Decompressing
Dict     Speed Usage    R/U Rating  |      Speed Usage    R/U Rating
         KiB/s     %   MIPS   MIPS  |      KiB/s     %   MIPS   MIPS
22:       9309   466   1945   9057  |     113067   568   1699   9642
23:       9036   454   2026   9207  |     110032   564   1688   9521
24:       9186   465   2122   9877  |     108373   567   1678   9512
25:       9337   469   2275  10661  |     106344   564   1679   9464
----------------------------------  | ------------------------------
Avr:             464   2092   9701  |              566   1686   9535
Tot:             515   1889   9618

Odroid N2

❯ 7z b
7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,6 CPUs LE)
LE
CPU Freq:  1597  1763  1797  1796  1795  1786  1792  1792  1791
RAM size:    3713 MB,  # CPU hardware threads:   6
RAM usage:   1323 MB,  # Benchmark threads:      6
Compressing  |                  Decompressing
Dict     Speed Usage    R/U Rating  |      Speed Usage    R/U Rating
         KiB/s     %   MIPS   MIPS  |      KiB/s     %   MIPS   MIPS
22:       5848   525   1083   5690  |     118603   535   1892  10115
23:       5615   530   1080   5722  |     114888   532   1868   9941
24:       5511   539   1099   5926  |     113151   536   1853   9932
25:       5223   540   1105   5964  |     107952   530   1812   9607
----------------------------------  | ------------------------------
Avr:             533   1092   5826  |              533   1856   9899
Tot:             533   1474   7862

RockPro64

❯ 7z b
7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,6 CPUs LE)
LE
CPU Freq: 64000000 - - - - - 512000000 - -
RAM size:    3793 MB,  # CPU hardware threads:   6
RAM usage:   1323 MB,  # Benchmark threads:      6
Compressing  |                  Decompressing
Dict     Speed Usage    R/U Rating  |      Speed Usage    R/U Rating
         KiB/s     %   MIPS   MIPS  |      KiB/s     %   MIPS   MIPS
22:       4468   476    913   4347  |      94209   522   1540   8034
23:       4114   473    886   4192  |      92694   525   1528   8021
24:       3965   472    902   4264  |      90617   525   1516   7954
25:       3840   480    913   4385  |      88555   525   1501   7881
----------------------------------  | ------------------------------
Avr:             475    904   4297  |              524   1521   7972
Tot:             500   1213   6135

Здесь мы видим, что NVIDIA Jetson NX на 22% быстрее Odroid-N2 и на 56% быстрее, чем RK3399 SOC от RockPro64.

Java SPECjvm2008

Раньше я сравнивал некоторые версии Java на ARM64, а также между некоторыми моими платами в одном и том же тесте, и он дает отличный баланс для демонстрации производительности процессора при различных типах рабочих нагрузок.

Здесь я сравниваю три платы, использованные в этих тестах:

В этом тесте мы видим, что в среднем по нескольким тестам SPECJvm2008 AmLogic SOC на 27% быстрее, чем RK3399. NVIDIA Xavier NX на 150% быстрее, чем AmLogic, и на 187% быстрее, чем RK3399.

Тесты памяти

Далее я протестировал производительность памяти с помощью sysbench. В этих тестах я использовал блоки размером 1К, 1М с тестами чтения и записи.

В тестах использовалось 50%, 100% и 200% памяти для каждой платы.

Xavier NX

❯ sysbench --test=memory --memory-block-size=1M --memory-total-size=8G run
sysbench 1.0.18 (using system LuaJIT 2.1.0-beta3)
Running the test with following options:
Number of threads: 1
Initializing random number generator from current time
Running memory speed test with the following options:
  block size: 1024KiB
  total size: 8192MiB
  operation: write
  scope: global
Initializing worker threads...
Threads started!
Total operations: 8192 (15042.72 per second)
8192.00 MiB transferred (15042.72 MiB/sec)
General statistics:
    total time:                          0.5421s
    total number of events:              8192
Latency (ms):
         min:                                    0.06
         avg:                                    0.07
         max:                                    0.50
         95th percentile:                        0.08
         sum:                                  532.89
Threads fairness:
    events (avg/stddev):           8192.0000/0.00
    execution time (avg/stddev):   0.5329/0.00

Odroid N2

❯ sysbench --test=memory --memory-block-size=1M --memory-total-size=4G run
sysbench 0.4.12:  multi-threaded system evaluation benchmark
Running the test with following options:
Number of threads: 1
Doing memory operations speed test
Memory block size: 1024K
Memory transfer size: 4096M
Memory operations type: write
Memory scope type: global
Threads started!
Done.
Operations performed: 4096 ( 1236.33 ops/sec)
4096.00 MB transferred (1236.33 MB/sec)
Test execution summary:
    total time:                          3.3130s
    total number of events:              4096
    total time taken by event execution: 3.3096
    per-request statistics:
         min:                                  0.29ms
         avg:                                  0.81ms
         max:                                  2.31ms
         approx.  95 percentile:               1.57ms
Threads fairness:
    events (avg/stddev):           4096.0000/0.00
    execution time (avg/stddev):   3.3096/0.00

RockPro64

rock64@rockpro64:~$ sysbench --test=memory --memory-block-size=1M --memory-total-size=8G run
WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options.
sysbench 1.0.18 (using system LuaJIT 2.1.0-beta3)
Running the test with following options:
Number of threads: 1
Initializing random number generator from current time
Running memory speed test with the following options:
  block size: 1024KiB
  total size: 8192MiB
  operation: write
  scope: global
Initializing worker threads...
Threads started!
Total operations: 8192 ( 7796.96 per second)
8192.00 MiB transferred (7796.96 MiB/sec)
General statistics:
    total time:                          1.0473s
    total number of events:              8192
Latency (ms):
         min:                                    0.12
         avg:                                    0.13
         max:                                    0.68
         95th percentile:                        0.13
         sum:                                 1044.03
Threads fairness:
    events (avg/stddev):           8192.0000/0.00
    execution time (avg/stddev):   1.0440/0.00

Ниже приведена таблица со всеми протестированными размерами блоков и объемом памяти.

Xavier в среднем на 200% быстрее доступ к памяти по сравнению с RockPro64 и на 500% быстрее, чем Odroid-N2. Это противоположное явление, которое мы видим при сравнении процессоров, где Odroid-N2 обычно быстрее, чем RockPro64.

Тесты машинного обучения

Чтобы протестировать ускорение Cuda GPU, я взял образец приложения из инфраструктуры PyTorch, которое представляет собой классификацию изображений MNIST. В этом случае я не сравнивал с другими платами ARM, поскольку ни у одной из них нет графического процессора. Тесты проводились на самой плате Xavier с ускорением графического процессора для рабочих нагрузок машинного обучения и без него. Вот где эта доска сияет.

Образец приложения можно найти здесь:



Выполнение выполняется в контейнере Docker, предоставленном NVIDIA, со всеми необходимыми требованиями PyTorch и установленными драйверами. Запустите Docker с помощью:

docker run -it --runtime=nvidia --rm -v $(pwd):/work -w /work nvcr.io/nvidia/l4t-pytorch:r32.4.2-pth1.5-py3

Вставьте его в mnist.py файл из Gist и выполните с time python3 mnist.py. Ниже приведены результаты тестирования:

С графическим процессором

Сначала образец был выполнен с полной поддержкой Cuda. Утилита jtop увеличивает использование ЦП примерно на 30–40%, в то время как частота графического процессора увеличилась до 1,1 ГГц и колеблется примерно на 40–75%.

root@40cb50bd2bc3:/work/pytorch# time python3 mnist.py --epochs=1
Train Epoch: 1 [0/60000 (0%)] Loss: 2.333409
..
Test set: Average loss: 0.0564, Accuracy: 9802/10000 (98%)
real 0m52.126s
user 1m2.100s
sys 0m8.316s

Я запустил 1 эпоху (1 итерация) с помощью команды time python3 mnist.py --epochs=1, и выполнение заняло 52,4 секунды.

Без графического процессора

Без ускорения графического процессора все 6 ядер работали на частоте 1,4 ГГц и все время 100%. Графический процессор остался на уровне 0%, как и ожидалось.

root@40cb50bd2bc3:/work/pytorch# time python3 mnist.py --epochs=1 --no-cuda
Train Epoch: 1 [0/60000 (0%)] Loss: 2.311259
..
Test set: Average loss: 0.0520, Accuracy: 9825/10000 (98%)
real 12m59.672s
user 65m59.436s
sys 0m44.076s

Выполнение 1 эпохи (1 итерация) с помощью команды time python3 mnist.py --epochs=1 --no-cuda заняло 12: 59,7 с. Да, вы правильно прочитали, почти 13 минут! Более чем в 13 раз дольше, чем время работы графического процессора.

Для сравнения, выполнение той же рабочей нагрузки на моем MacBook Pro 15 '' 2018 (6-ядерный Intel Core i7 с тактовой частотой 2,6 ГГц) без графического процессора CUDA в контейнере Docker, работающем в виртуальной машине с 10 ядрами и 6 ГБ ОЗУ, потребовало:

> docker run -it --rm -v $(pwd):/work -w /work --rm pytorch/pytorch bash
> time python3 mnist.py --epochs=1
....
real 1m39.388s
user 5m32.886s
sys 1m6.857s

Удивительно, что крошечный графический процессор в небольшом бортовом компьютере, потребляющем намного меньше энергии, может выполнять ту же рабочую нагрузку почти вдвое быстрее, чем ноутбук высшего класса.

TensorFlow 2

Для тестов TensorFlow 2 я использовал другой образец MNIST. Приложение основано на этом файле, но требует некоторых корректировок. Я загрузил его в this Gist.

Поскольку NVIDIA создает образы контейнеров только для TensorFlow 1.5, для этого теста я создал Dockerfile для TF2. Образ был помещен в DockerHub с тегом carlosedp/l4t-tensorflow:r32.4.2-tf1-py3.

Тесты выполнялись с помощью Docker с использованием nvidia-runtime для ускорения графического процессора или без него только для процессора.

Любопытно, что я видел очень похожие времена между исполнениями CPU и GPU. Я даже открыл ветку на форумах NVIDIA и, попробовав эти предложения, получил аналогичные цифры.

GPU

Контейнер выполнен с docker run -it --runtime=nvidia --rm -v $(pwd):/work -w /work carlosedp/l4t-tensorflow:r32.4.2-tf2-py3 bash

> python3 mnist.py
...
2020-06-12 19:59:30.666323: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1241] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 3560 MB memory) -> physical GPU (device: 0, name: Xavier, pci bus id: 0000:00:00.0, compute capability: 7.2)
2020-06-12 19:59:32.241779: I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library libcublas.so.10
step: 100, loss: 0.373517, accuracy: 0.898438
step: 200, loss: 0.250729, accuracy: 0.933594
...
Test Accuracy: 0.966400
real 0m52.721s
user 0m51.516s
sys 0m5.936s

ЦП

Контейнер выполнен с docker run -it --rm -v $(pwd):/work -w /work carlosedp/l4t-tensorflow:r32.4.2-tf2-py3 bash

> python3 mnist.py
...
2020-06-12 19:57:30.661145: W tensorflow/stream_executor/platform/default/dso_loader.cc:59] Could not load dynamic library 'libcudart.so.10.2'; dlerror: libcudart.so.10.2: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/cuda/lib64:/usr/local/cuda-10.2/targets/aarch64-linux/lib:
2020-06-12 19:57:30.661284: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.
step: 100, loss: 0.347883, accuracy: 0.914062
step: 200, loss: 0.248891, accuracy: 0.933594
...
Test Accuracy: 0.964100
real 0m51.953s
user 1m14.548s
sys 0m4.824s

Как видите, довольно похожие времена. Также я не видел, чтобы GPU на jtop выходил более чем на 25–30% на частоте 114 МГц (минимум) в режиме GPU. Может быть, кто-нибудь, кто знает TensorFlow и Keras, отправит мне отзыв.

Потребляемая мощность

Jetson Xavier NX потребляет около 7,3 Вт в режиме ожидания и превышает 11,7 Вт в 6-ядерном режиме в 1,4 ГГц и 9,6 Вт в 2-ядерном режиме 1,9 ГГц.

Это как минимум в 1,8 раза выше энергопотребления при полном использовании и в 2,5 раза выше в режиме ожидания по сравнению с Odroid-N2, который я проверил.

Во время теста Pytorch MNIST я видел пики в 13,5 Вт при использовании графического процессора и 10,2 Вт только на процессоре. Учитывая количество времени, которое потребовалось на тест, ускорение графического процессора стоит того, поскольку на его выполнение ушло в 13 раз меньше времени.

Вывод

В общем, плата NVIDIA Jetson Xavier NX - это мощный компьютер с большей вычислительной мощностью, который я видел на большинстве SBC ARM. Благодаря его графическому процессору, открываются новые возможности для обработки рабочих нагрузок машинного обучения на периферии, опережая процессорную обработку сравнительно недавнего компьютера (MacBook Pro 2018).

Xavier NX также является отличным вариантом в качестве настольного компьютера в сочетании с твердотельным накопителем M.2 (для большей производительности и свободного пространства) и может использоваться в качестве повседневного драйвера для большинства задач разработки.

Слабым местом является его цена, которая намного превосходит большинство SBC и составляет 399 долларов, но с учетом производительности процессора и оперативной памяти, графического процессора, слота M.2 и экосистемы NVIDIA она находится в другой категории, близкой к той, что была бы рабочая станция ARM.

Если у вас есть предложения или идеи по тестированию на этих досках, присылайте мне свой отзыв в Twitter @carlosedp.