Русский
Русский
English
Статистика
Реклама

Бенчмарки

Новогодние бенчмарки компьютеров Эльбрус

29.12.2020 02:22:15 | Автор: admin

Новогодние бенчмарки компьютеров Эльбрус


LuaBenchmarks.png


Продолжение статьи Большое тестирование процессоров различных архитектур. В этот раз я решил измерить производительность конкретных сред/языков программирования (C#, Java, JavaScript, Python, Lua) на компьютерах с процессорами Эльбрус и сравнить их с компьютерами (даже телефонами) на процессорах архитектурой ARM и X86-64.


Языки программирования:


  • C#
  • PHP
  • JavaScript (Browser, не NodeJS)
  • Java
  • Python
  • Lua

Список тестов



Но сперва приведу результаты нативных бенчмарков на языке C, а также результаты других популярных бенчмарков.


Тестовые стенды и их процессоры


А пока можете опробовать JavaScript версию бенчмарка: http://laseroid.azurewebsites.net/js-bench/


Стенды на процессорах x86 (i386) х86-64 (amd64):



Компилируемые бенчмарки на C/C++


Таблица с результатами с прошлой статьи


Результаты нативных бенчмарков

Тут выходит так: компьютеры на Эльбрусах имеют сопоставимую производительность с Intel Core i7 2600, если бы он работал на частоте 1200 1300 МГц (Для Эльбрус-8С), кроме теста MP MFLOPS, который хорошо распараллеливается компилятором LCC и для Эльбрус 8СВ выдаёт 325 ГФлопс, где Core i7 2600 выдавал
85 ГФлопс (Это с SSE, без AVX).


Задержки кеша. Тест TLB от Линуса Торвальдса


Cpu Elbrus 2C+ Elbrus 4C Elbrus 8C Elbrus 8CB Elbrus R1000 Allwinner A64 Amd A6 3650
Freq (MHz) 500 750 1300 1550 1000 1152 2600
Cores 2 4 8 8 4 4 4
4k 14.02ns 4.04ns 2.51ns 1.94ns 45.01ns 3.48ns 1.16ns
4k cycles 7.0 3.0 3.0 3.0 5.0 4.0 3.0
8k 14.02ns 4.04ns 2.51ns 1.94ns 5.01ns 3.48ns 1.16ns
8k cycles 7.0 3.0 3.0 3.0 5.0 4.0 3.0
16k 14.02ns 4.04ns 2.51ns 1.94ns 5.01ns 3.48ns 1.16ns
16k cycles 7.0 3.0 3.0 3.0 5.0 4.0 3.0
32k 14.03ns 4.04ns 2.51ns 1.94ns 5.16ns 3.58ns 1.16ns
32k cycles 7.0 3.0 3.0 3.0 5.2 4.1 3.0
64k 14.04ns 4.06ns 2.51ns 1.94ns 23.45ns 6.83ns 1.16ns
64k cycles 7.0 3.0 3.0 3.0 23.4 7.9 3.0
128k 18.04ns 14.83ns 9.19ns 7.10ns 23.75ns 7.28ns 4.00ns
128k cycles 9.0 11.1 11.0 11.0 23.7 8.4 10.4
256k 24.97ns 14.82ns 9.19ns 7.10ns 23.98ns 7.69ns 4.00ns
256k cycles 12.5 11.1 11.0 11.0 24.0 48.9 10.4
512k 22.26ns 14.82ns 9.28ns 7.13ns 24.12ns 8.04ns 4.00ns
512k cycles 11.1 11.1 11.1 11.1 24.1 9.3 10.4
1M 67.80ns 14.83ns 27.57ns 21.31ns 24.07ns 34.36n 4.03ns
1M cycles 33.9 11.1 33.1 33.0 24.1 39.6 10.5
2M 106.21ns 22.49ns 27.56ns 21.31ns 46.62ns 37.05n 12.14ns
2M cycles 53.1 16.9 33.1 33.0 46.6 42.7 31.6
4M 107.51ns 120.65ns 27.56ns 21.31ns 119.53ns 37.36n 12.06ns
4M cycles 53.8 90.5 33.1 33.0 119.5 43.0 31.3
8M 107.92ns 121.18ns 27.57ns 21.31ns 141.08ns 37.37n 12.21ns
8M cycles 54.0 90.9 33.1 33.0 141.1 43.0 31.7
16M 107.86ns 121.27ns 47.72ns 31.54ns 143.90ns 37.57n 12.01ns
16M cycles 53.9 90.9 57.3 48.9 143.9 43.3 31.2
32M 107.91ns 119.22ns 111.71ns 117.28ns 144.34ns 37.09n 12.02ns
32M cycles 54.0 89.4 134.1 181.8 144.3 42.7 31.3
64M 107.91ns 119.48ns 149.90ns 117.39ns 144.36ns 37.07n 11.98ns
64M cycles 54.0 89.6 179.9 182.0 144.4 42.7 31.2
128M 107.91ns 121.75ns 169.79ns 117.51ns 144.42ns 37.57n 12.02ns
128M cycles 54.0 91.3 203.7 182.1 144.4 43.3 31.3
256M 107.97ns 122.11ns 174.90ns 117.58ns 144.34ns 37.77n 12.21ns
256M cycles 54.0 91.6 209.9 182.3 144.3 43.5 31.7

Задержки кеша на Эльбруса 8СВ таковы:


  • L1: 3 такта с 1,94 нс
  • L2: 11 тактов с 7,1 нс
  • L3: 3 такта с 21,31 нс
  • ОЗУ: 90-180 тактов с 117 нс

Характеристики кеша для Эльбрус 8С можно посмотреть здесь: Архитектура Эльбрус 8С


Исходный код: Test TLB


Тесты памяти STREAM


Array size = 10000000 (elements), Offset = 0 (elements)

Memory per array = 76.3 MiB (= 0.1 GiB).

Total memory required = 228.9 MiB (= 0.2 GiB).

CPU Frequency Threads Memory Type Copy (MB/s) Scale (MB/s) Add (MB/s) Triad (MB/s)
Elbrus 4C 750 4 DDR3-1600 9 436.30 9 559.70 10 368.50 10 464.80
Elbrus 8C 1300 8 DDR3-1600 11 406.70 11 351.70 12 207.50 12 355.10
Elbrus 8CB 1550 8 DDR4-2400 23 181.80 22 965.20 25 423.90 25 710.20
Allwinner A64 1152 4 LPDDR3-800 2 419.90 2 421.30 2 112.70 2 110.10
AMD A6-3650 2600 4 DDR3-1333 6 563.60 6 587.90 7 202.80 7 088.00

Исходный код: STREAM


Geekbench 4/5 (В режиме RTC: x86 -> e2k трансляция)


Geekbench 5


CPU Frequency Threads Single Thread Multi Thread
Эльбрус 8С 1300 8 142 941
Эльбрус 8СВ 1550 8 159 1100
Intel Core i7 2600 3440 8 720 2845
Amd A6 3650 2600 4 345 1200

Geekbench 4


CPU Frequency Threads Single Thread Multi Thread
Эльбрус 8С 1300 8 873 3398
Эльбрус 8СВ 1550 8 983 4042
Intel Pentium 4 2800 1 795 766
Intel Core i7 2600 3440 8 3702 12063
Qualcomm 625 2000 8 852 2829

Crystal Mark 2004 (В режиме RTC: x86 -> e2k трансляция)


CPU Threads Frequency ALU FPU MEM R (Mb/s) MEM W (Mb/s) Anounced
486 DX4 1 75 119 77 9 11 1993
P1 (P54C) 1 200 484 420 80 65 1994
P1 MMX (P55C) 1 233 675 686 112 75 1997
P2 1 400 1219 1260 222 150 1998
Transmeta Crusoe TM5800 1 1000 2347 1689 405 223 2000
P3 (Coopermine) 1 1000 3440 3730 355 170 2000
P4 (Willamete) 1 1600 3496 4110 1385 662 2001
Celeron (Willamete) 1 1800 3934 4594 1457 657 2001
Athlon XP (Palomino) 1 1400 4450 6220 430 520 2001
P4 (Northwood) 1 2400 5661 6747 1765 754 2002
P4 (Prescott) 1 2800 5908 6929 3744 851 2004
Athlon 64 (Venice) 1 1800 6699 7446 1778 906 2005
Celeron 530 (Conroe-L) 1 1733 7806 9117 3075 1226 2006
P4 (Prescott) 2 3000 9719 10233 3373 1578 2004
Atom D525 4 1800 10505 7605 3407 1300 2010
Athlon 64 X2 (Brisbane) 2 2300 16713 19066 3973 2728 2007
Core i3-6100 2 3700 17232 10484 5553 9594 2015
Pentium T3200 (Merom) 2 2000 20702 18063 4150 1598 2008
Atom x5-Z8350 4 1440 21894 18018 4799 2048 2016
Core i3-M330 4 2133 25595 26627 6807 4257 2010
Core 2 Duo 2 3160 28105 18196 6850 2845 2008
Atom Z3795 4 1600 40231 34963 12060 5797 2016
AMD A6-3650 4 2600 46978 35315 9711 3870 2011
Core 2 Quad 4 2833 47974 31391 9710 5493 2008
Core i3-4130 4 3400 54296 39163 19450 9269 2013
AMD Phenom II X4 965 (Agena) 4 3400 59098 56272 11162 5973 2009
Core i7-2600 8 3400 95369 71648 19547 9600 2011
Core i7-9900K 16 3600 270445 238256 44618 17900 2018
Elbrus-8C RTC-x86 8 1300 65817 29977 49800 7945 2016
Elbrus-8CB RTC-x86 8 1500 77481 37972 62100 13940 2018
Elbrus-1C+ RTC-x86 1 1000 6862 2735 6230 1800 2015

Процессор Эльбрус-8С 1.3 ГГц на уровне AMD Phenom II X4 965 3.4 ГГц 4 ядра. 8СВ на 20% быстрее.


Бенчмарки сред/языков программирования


А теперь переходим к бенчмаркам языков программирования (C#, Java, JavaScript, Python, Lua).


Исходный код здесь: https://github.com/EntityFX/EntityFX-Bench
Исходный код для прощлых бенчмарков можете найти тут: https://github.com/EntityFX/anybench


Микро бенчмарки


В цикле с большим числоv итераций проводим некоторые операции и замеряем время выполнения данного куска кода. Ниже буду приводить примеры на языке Python.


Arithmetics


Замеряет скорость арифметики: в цикле выполняет различные математические операции с замером времени выполнения.


Пример кода на Python:


    @staticmethod    def _doArithmetics(i : int) -> float:        return math.floor(i / 10) * math.floor(i / 100) * math.floor(i / 100) * math.floor(i / 100) * 1.11) + math.floor(i / 100) * math.floor(i / 1000) * math.floor(i / 1000) * 2.22 - i * math.floor(i / 10000) * 3.33 + i * 5.33

Math


Замеряет скорость математических функций (Cos, Sin, Tan, Log, Power, Sqrt):


    @staticmethod    def _doMath(i : int, li : float) -> float:        rev = 1.0 / (i + 1.0)        return (math.fabs(i) * math.acos(rev) * math.asin(rev) * math.atan(rev) + math.floor(li) + math.exp(rev) * math.cos(i) * math.sin(i) * math.pi) + math.sqrt(i)

Loops


Замеряет скорость работы холостых циклов. Кстати, некоторые компиляторы и рантаймы могут оптимизировать этот код.


Conditions


Замеряет скорость работы условий.


        d = 0        i = 0; c = -1        while i < self._iterrations:             c = ((-1 if c == (-4) else c))            if (i == (-1)):                 d = 3            elif (i == (-2)):                 d = 2            elif (i == (-3)):                 d = 1            d = (d + 1)            i += 1; c -= 1        return d

Array speed (Memory, Random Memory)


Замеряет скорость чтения из массива в переменную (последовательно или со случайными индексами)


Большой кусок кода на Python
    def _measureArrayRead(self, size) :        block_size = 16        i = [0] * block_size        array0_ = list(map(lambda x: random.randint(-2147483647, 2147483647), range(0, size)))        end = len(array0_) - 1        k0 = math.floor(size / 1024)        k1 = 1 if k0 == 0 else k0        iter_internal = math.floor(self._iterrations / k1)        iter_internal = 1 if iter_internal == 0 else iter_internal        idx = 0        while idx < end:             i[0] = (array0_[idx])            i[1] = (array0_[idx + 1])            i[2] = (array0_[idx + 2])            i[3] = (array0_[idx + 3])            i[4] = (array0_[idx + 4])            i[5] = (array0_[idx + 5])            i[6] = (array0_[idx + 6])            i[7] = (array0_[idx + 7])            i[8] = (array0_[idx + 8])            i[9] = (array0_[idx + 9])            i[0xA] = (array0_[idx + 0xA])            i[0xB] = (array0_[idx + 0xB])            i[0xC] = (array0_[idx + 0xC])            i[0xD] = (array0_[idx + 0xD])            i[0xE] = (array0_[idx + 0xE])            i[0xF] = (array0_[idx + 0xF])            idx += block_size        start = time.time()        it = 0        while it < iter_internal:             idx = 0            while idx < end:                 i[0] = (array0_[idx])                i[1] = (array0_[idx + 1])                i[2] = (array0_[idx + 2])                i[3] = (array0_[idx + 3])                i[4] = (array0_[idx + 4])                i[5] = (array0_[idx + 5])                i[6] = (array0_[idx + 6])                i[7] = (array0_[idx + 7])                i[8] = (array0_[idx + 8])                i[9] = (array0_[idx + 9])                i[0xA] = (array0_[idx + 0xA])                i[0xB] = (array0_[idx + 0xB])                i[0xC] = (array0_[idx + 0xC])                i[0xD] = (array0_[idx + 0xD])                i[0xE] = (array0_[idx + 0xE])                i[0xF] = (array0_[idx + 0xF])                idx += block_size            it += 1        elapsed = time.time() - start        return (iter_internal * len(array0_) * 4 / elapsed / 1024 / 1024, i)

String manipulation


Скорость работы со строковыми функциями (replace, upper, lower)


    @staticmethod    def _doStringManipilation(str0_ : str) -> str:        return ("/".join(str0_.split(' ')).replace("/", "_").upper() + "AAA").lower().replace("aaa", ".")

Hash algorithms


Алгоритмы SHA1 и SHA256 над байтами строк.


    @staticmethod    def _doHash(i : int, prepared_bytes):        hashlib.sha1()        sha1_hash = hashlib.sha1(prepared_bytes[i % 3]).digest()        sha256_hash = hashlib.sha256(prepared_bytes[(i + 1) % 3]).digest()        return sha1_hash + sha256_hash

Комплексные бенчмарки


Выполнил реализацию популярных бенчмарков Dhrystone, Whetstone, LINPACK, Scimark 2 на всех 5 языках программирования (конечно же использовал существующие исходники, но адаптировал под мои тесты).


Dhrystone


Dhrystone синтетический тест, который был написан Reinhold P. Weicker в 1984 году.
Данный тест не использует операции с плавающей запятой, а версия 2.1 написана так, чтобы исключить возможность сильных оптимизаций при компиляции.
Бенчмарк выдаёт результаты в VAX Dhrystones в секунду, где 1 VAX DMIPS = Dhrystones в секунду делить на 1757.

Whetstone


Whetstone синтетический тест, который был написан Harold Curnow в 1972 году на языке Fortran.
Позже был переписан на языке C Roy Longbottom. Данный тест выдаёт результаты в MWIPS,
также промежуточные результаты в MOPS (Миллионов операций в секунду) и MFLOPS (Миллионы вещественных операций с плавающей запятой в секунду).
Данный тест производит различные подсчёты: производительность целочисленных и операций с плавающей запятой,
производительность операций с массивами, с условным оператором, производительность тригонометрических функций и функций возведения в степень, логарифмов и извлечения корня.

LINPACK


LINPACK тест, который был написан Jack Dongarra на языке Fortran в 70х годах, позже переписан на язык C.
Тест считает системы линейных уравнений, делает различные операции над двумерными (матрицами) и одномерными (векторами).
Используется реализация Linpack 2000x2000.

Scimark 2


SciMark 2 набор тестов на языке C измеряющий производительность кода встречающегося в научных и профессиональных приложениях. Содержит в себе 5 вычислительных тестов: FFT (быстрое преобразование Фурье), Gauss-Seidel relaxation (Метод Гаусса Зейделя для решения СЛАУ), Sparse matrix-multiply (Умножение разреженных матриц), Monte Carlo integration (Интегрирование методом Монте-Карло), и LU factorization (LU-разложение).

Переходим к результатам.


Результаты


Бенчмарки Java


Результаты нативных бенчмарков

Результаты Java на Эльбрусах в сравнении с Core i7 2600 4 ядра, 8 потоков 3.4 ГГц:


  • Эльбрус 1С+ в 11 раз медленнее на 1 поток
  • Эльбрус 4С в 10 раз медленнее на 1 поток
  • Эльбрус 8С в 5,5 раз медленнее на 1 поток
  • Эльбрус 8СВ в 4,5 раз медленнее на 1 поток
  • Эльбрус 1С+ в 18 раз медленнее на всех потоках
  • Эльбрус 4С в 12,5 раз медленнее на всех потоках
  • Эльбрус 8С в 3 раз медленнее на всех потоках
  • Эльбрус 8СВ в 2,5 раз медленнее на всех потоках

Результаты Java на Эльбрусах в сравнении с Core i7 2600 4 ядра, 8 потоков, но на одинаковых частотах:


  • Эльбрус 1С+ в 3,5 раз медленнее на 1 поток Core i7 2600 на частоте 1 ГГц
  • Эльбрус 4С в 2,5 раз медленнее на 1 поток Core i7 2600 на частоте 0,8 ГГц
  • Эльбрус 8С в 2 раз медленнее на 1 поток Core i7 2600 на частоте 1,3 ГГц
  • Эльбрус 8СВ в 2 раз медленнее на 1 поток Core i7 2600 на частоте 1,55 ГГц
  • Эльбрус 1С+ в 5 раз медленнее на всех потоках Core i7 2600 на частоте 1 ГГц
  • Эльбрус 4С в 2,75 раз медленнее на всех потоках Core i7 2600 на частоте 0,8 ГГц
  • Эльбрус 8С в 1,15 раз медленнее на всех потоках Core i7 2600 на частоте 1,3 ГГц
  • Эльбрус 8СВ в 1,15 раз медленнее на всех потоках Core i7 2600 на частоте 1,55 ГГц

Для Java делали очень серьёзные оптимизации, поэтому отставание в 2 раза на одинаковых частотах не является плохим результатом.


Про то, как оптимизировали Java можно почитать тут: Java на Эльбрусе


Посмотреть здесь:



Бенчмарки C# (.Net Framework, .Net Core, Mono)


Результаты бенчмарков на C#

DotnetBenchmarks.png


Так как сред исполнения несколько (.Net Framework, .Net Core, Mono), то я старался сравнивать одинаковые среды исполнения, т. е. Mono на e2k c Mono на x86.


Результаты C# (Mono) на Эльбрусах в сравнении с Core i7 2600 4 ядра, 8 потоков 3.4 ГГц:


  • Эльбрус 1С+ в 15,5 раз медленнее на 1 поток
  • Эльбрус 4С в 19 раз медленнее на 1 поток
  • Эльбрус 8С в 10,5 раз медленнее на 1 поток
  • Эльбрус 8СВ в 8 раз медленнее на 1 поток
  • Эльбрус 1С+ в 24 раз медленнее на всех потоках
  • Эльбрус 4С в 12,5 раз медленнее на всех потоках
  • Эльбрус 8С в 4,5 раз медленнее на всех потоках
  • Эльбрус 8СВ в 4 раз медленнее на всех потоках

Результаты C# (Mono) на Эльбрусах в сравнении с Core i7 2600 4 ядра, 8 потоков, но на одинаковых частотах:


  • Эльбрус 1С+ в 4,5 раз медленнее на 1 поток Core i7 2600 на частоте 1 ГГц
  • Эльбрус 4С в 4,2 раз медленнее на 1 поток Core i7 2600 на частоте 0,8 ГГц
  • Эльбрус 8С в 3 раз медленнее на 1 поток Core i7 2600 на частоте 1,3 ГГц
  • Эльбрус 8СВ в 3 раза медленнее на 1 поток Core i7 2600 на частоте 1,55 ГГц
  • Эльбрус 1С+ в 7 раз медленнее на всех потоках Core i7 2600 на частоте 1 ГГц
  • Эльбрус 4С в 3 раза медленнее на всех потоках Core i7 2600 на частоте 0,8 ГГц
  • Эльбрус 8С в 1,5 раз медленнее на всех потоках Core i7 2600 на частоте 1,3 ГГц
  • Эльбрус 8СВ в 1,2 раз медленнее на всех потоках Core i7 2600 на частоте 1,55 ГГц

Результаты C# (NetCore) в режиме RTC на Эльбрусах в сравнении с Core i7 2600 4 ядра, 8 потоков 3.4 ГГц:


  • Эльбрус 8С в 3,5 раз медленнее на 1 поток Core i7 2600 на частоте 1,3 ГГц
  • Эльбрус 8СВ в 3 раз медленнее на 1 поток Core i7 2600 на частоте 1,55 ГГц
  • Эльбрус 8С в 2 раз медленнее на всех потоках Core i7 2600 на частоте 1,3 ГГц
  • Эльбрус 8СВ в 1,5 раз медленнее на всех потоках Core i7 2600 на частоте 1,55 ГГц

Результаты C# (NetCore) в режиме RTC на Эльбрусах в сравнении с Core i7 2600 4 ядра, 8 потоков, но на одинаковых частотах:


  • Эльбрус 8С в 1,3 раз медленнее на 1 поток Core i7 2600 на частоте 1,3 ГГц
  • Эльбрус 8СВ в 1,2 раз медленнее на 1 поток Core i7 2600 на частоте 1,55 ГГц
  • Эльбрус 8С в 1,25 раза быстрее на всех потоках Core i7 2600 на частоте 1,3 ГГц
  • Эльбрус 8СВ в 1,25 раза быстрее на всех потоках Core i7 2600 на частоте 1,55 ГГц

Mono сам по себе является достаточно медленной средой выполнения по сравнению с Net Fremework, а особенно с NetCore (до 3х раз). Что достаточно допустимо. Здесь я не знаю, делали ли оптимизации как это было сделано с Java.


Выходит NetCore в режиме RTC на Эльбрусах работает до 4х раз быстрее чем Mono. Будем ждать нативного NetCore для e2k.


Бенчмарки JavaScript (Браузерные)


JavaScript версия бенчмарка: http://laseroid.azurewebsites.net/js-bench/


Результаты бенчмарков на JavaScript

Результаты JavaScript на Эльбрусах в сравнении с Core i7 2600 4 ядра, 8 потоков 3.4 ГГц:


  • Эльбрус 1С+ в 16 раз медленнее
  • Эльбрус 4С в 12,5 раз медленнее
  • Эльбрус 8С в 6,5 раз медленнее
  • Эльбрус 8СВ в 5 раз медленнее

Результаты JavaScript на Эльбрусах в сравнении с Core i7 2600 4 ядра, 8 потоков, но на одинаковых частотах:


  • Эльбрус 1С+ в 5 раз медленнее Core i7 2600 на частоте 1 ГГц
  • Эльбрус 4С в 2,75 раза медленнее Core i7 2600 на частоте 0,8 ГГц
  • Эльбрус 8С в 2,5 раза медленнее Core i7 2600 на частоте 1,3 ГГц
  • Эльбрус 8СВ в 2,25 раз медленнее Core i7 2600 на частоте 1,55 ГГц

Другие популярные JavaScript бенчмарки


Octane


Firefox (версии разные)


Cpu Result (баллы)
Intel Core i7 2600 23321
AMD A6-3650 11741
Intel Pentium 4 2800 3387
Elbrus 8C (rtc x86 32bit) 2815
Elbrus 8C 2102
Elbrus 1C+ 739

Kraken Benchmark


Firefox (версии разные)


Cpu Result (ms)
Elbrus 8C 10493.4
Elbrus 8CB RTX x86 9567.5
Elbrus 8CB 8714.2
Intel Pentium 4 2800 9486.6
AMD A6-3650 3052.5
Intel Core i7 2600 (3.4 GHz) 1456.8

Sunspider


Firefox (версии разные)


Cpu Result (ms)
Elbrus 8C 3059.8
Elbrus 8CB 2394.6
Intel Pentium 4 2800 1295.5
AMD A6-3650 485.6
Intel Core i7 2600 (3.4 GHz) 242.9

Результаты слабоваты. Причина: низкие тактовые частоты и недостаточная оптимизация. Но это гораздо лучше, чем было раньше. Также браузер FX52 уже старый, а будет новая, надеюсь, там уже допилили JavaScript.


Бенчмарки PHP


Результаты бенчмарков на PHP

Результаты PHP на Эльбрусах в сравнении с Core i7 2600 3.4 ГГц:


  • Эльбрус 2С+ в 15,5 раз медленнее
  • Эльбрус 1С+ в 8 раз медленнее
  • Эльбрус 4С в 4,5 раза медленнее
  • Эльбрус 8С в 3 раза медленнее
  • Эльбрус 8СВ в 2,5 раза медленнее
  • Эльбрус R1000 в 12,5 раз медленнее

Результаты PHP на Эльбрусах в сравнении с Core i7 2600, но на одинаковых частотах:


  • Эльбрус 2С+ в 2,3 раз медленнее Core i7 2600 на частоте 0,5 ГГц
  • Эльбрус 1С+ в 2,3 раз медленнее Core i7 2600 на частоте 1 ГГц
  • Эльбрус 4С = Core i7 2600 на частоте 0,8 ГГц
  • Эльбрус 8С в 1,1 раза медленнее Core i7 2600 на частоте 1,3 ГГц
  • Эльбрус 8СВ в 1,1 раза медленнее Core i7 2600 на частоте 1,55 ГГц
  • Эльбрус R1000 в 3,75 раз медленнее Core i7 2600 на частоте 1 ГГц

PHP показывает почти равную скорость на одинаковых частотах с Intel процессорами. Причина проста: здесь МЦСТ делали оптимизацию. Очень удивительно для интерпретируемого языка. Кстати, хочу обратить внимание на то что PHP 7.4 стал быстрее версии PHP 5.6 в 1,5 раза, поэтому я запускал бенчмарки на 2х версиях на Core i7 2600.


Другие популярные PHP бенчмарки


PHP Simple Benchmark


Test Elbrus 8C Elbrus 8CB Pentium 4 2800 AMD A6-3650 Core i7-2600 Allwinner A64
Frequency 1300 1550 2800 2600 3400 1152
CPU Threads 8 8 1 4 8 (4) 4
Version 7.0.33 7.0.33 7.2.24 7.4.3 7.0.33 5.6.20 7.0.33
01_math (kOp/s) 58.15 69.72 104.19 295.97 308.94 131.73 44.33
02_string_concat (MOp/s) 3.56 3.92 4.00 13.15 5.52 0.56 3.07
03_1_string_number_concat (kOp/s) 418.29 472.77 631.10 1510.00 1680.00 1600.00 332.99
03_2_string_number_format (kOp/s) 506.39 573.89 724.44 1690.00 1810.00 1620.00 432.88
04_string_simple_functions (kOp/s) 77.06 91.50 198.03 332.67 39.12 57.60 59.48
05_string_multibyte (kOp/s) 2.48 2.90 -.-- 57.53 11.01 12.77 2.50
06_string_manipulation (kOp/s) 22.10 26.91 78.96 127.08 14.11 23.96 35.73
07_regex (kOp/s) 48.24 54.60 128.41 233.76 334.99 62.43 47.64
08_1_hashing (kOp/s) 113.58 132.62 180.46 306.24 345.52 270.31 71.44
08_2_crypt (Op/s) 361.21 403.62 571.99 813.60 460.00 454.15 238.00
09_json_encode (kOp/s) -.-- -.-- 88.33 233.62 313.52 191.66 48.67
10_json_decode (kOp/s) -.-- -.-- 68.02 143.01 211.62 94.15 33.57
11_serialize (kOp/s) 73.67 81.57 130.16 307.52 435.66 263.06 62.20
12_unserialize (kOp/s) 63.89 69.02 79.33 301.98 348.62 258.75 46.21
13_array_fill (MOp/s) 2.08 2.50 5.30 9.69 14.07 5.35 1.97
14_array_range (kOp/s) 50.36 57.54 31.68 61.01 1140.00 30.35 25.25
14_array_unset (MOp/s) 2.08 2.48 7.17 14.05 14.45 7.32 2.16
15_loops (MOp/s) 13.57 16.21 38.75 150.46 78.92 42.54 12.64
16_loop_ifelse (MOps/s) 4.74 5.64 13.41 28.34 19.04 18.72 4.48
17_loop_ternary (MOp/s) 3.18 3.79 7.29 12.10 11.40 11.85 2.90
18_1_loop_defined_access (MOp/s) 3.28 3.90 9.03 18.90 18.29 15.35 3.18
18_2_loop_undefined_access (MOp/s) 0.60 0.66 1.13 2.60 2.40 2.10 0.49
19_type_functions (MOp/s) 250.57 293.21 806.37 1560.00 1180.00 971.77 193.89
20_type_conversion (MOp/s) 382.32 458.44 812.72 1570.00 1530.00 1510.00 298.61
21_0_loop_exception_none (MOp/s) 7.45 8.91 19.67 56.57 26.35 15.67 6.97
21_1_loop_exception_try (MOp/s) 6.48 7.74 19.11 52.18 23.61 18.99 6.39
21_2_loop_exception_catch (kOp/s) 184.22 216.00 573.09 1380.00 1240.00 498.60 147.28
22_loop_null_op (MOp/s) 3.25 3.74 8.39 16.03 17.62 -.-- 3.08
23_loop_spaceship_op (MOp/s) 4.30 5.12 8.50 17.98 20.39 -.-- 3.96
24_xmlrpc_encode (Op/) -.-- -.-- -.-- -.-- 17.6 -.-- -.--
25_xmlrpc_decode (Op/) -.-- -.-- -.-- -.-- 9.16 -.-- -.--
26_1_class_public_properties (MOp/s) 3.32 4.08 10.51 26.70 19.57 9.42 3.22
26_2_class_getter_setter (MOp/s) 1.31 1.51 4.66 9.41 5.52 4.13 0.97
26_3_class_magic_methods (MOp/s) 0.52 0.59 1.35 3.77 3.21 1.89 0.41
Total (MOp/s) 1.23 1.43 2.60 5.33 2.48 2.02 0.98
Time (sec) 488.324 419.895 231.485 113.087 252.376 261.652 609.787

Бенчмарки Python


Результаты бенчмарков на Python

Так как под Windows не удалось запустить многопоточный Python (я не Питонист, да и времени сделать универсальную многопоточность на всех ОС не было, принимаю патчи), приведу относительно Amd A6 3650, который на 40% медленнее Core i7.


Результаты Python на Эльбрусах в сравнении с Core i7 2600 3.4 ГГц:


  • Эльбрус 2С+ в 30 раз медленнее на 1 поток
  • Эльбрус 1С+ в 12,5 раз медленнее на 1 поток
  • Эльбрус 4С в 15,5 раз медленнее на 1 поток
  • Эльбрус 8С в 9 раз медленнее на 1 поток
  • Эльбрус 8СВ в 7,8 раз медленнее на 1 поток
  • Эльбрус 2С+ в 58 раз медленнее на всех потоках
  • Эльбрус 1С+ в 25 раз медленнее на всех потоках
  • Эльбрус 4С в 13,5 раз медленнее на всех потоках
  • Эльбрус 8С в 4,2 раза медленнее на всех потоках
  • Эльбрус 8СВ в 3,8 раза медленнее на всех потоках

Результаты Python на Эльбрусах в сравнении с Core i7 2600, но на одинаковых частотах:


  • Эльбрус 2С+ в 4,5 раз медленнее на 1 поток Core i7 2600 на частоте 0,5 ГГц
  • Эльбрус 1С+ в 3,6 раз медленнее на 1 поток Core i7 2600 на частоте 1 ГГц
  • Эльбрус 4С в 3,5 раз медленнее на 1 поток Core i7 2600 на частоте 0,8 ГГц
  • Эльбрус 8С в 3,5 раз медленнее на 1 поток Core i7 2600 на частоте 1,3 ГГц
  • Эльбрус 8СВ в 3,5 раз медленнее на 1 поток Core i7 2600 на частоте 1,55 ГГц
  • Эльбрус 2С+ в 8,5 раз медленнее на всех потоках Core i7 2600 на частоте 0,5 ГГц
  • Эльбрус 1С+ в 7,4 раз медленнее на всех потоках Core i7 2600 на частоте 1 ГГц
  • Эльбрус 4С в 3 раз медленнее на всех потоках Core i7 2600 на частоте 0,8 ГГц
  • Эльбрус 8С в 1,5 раза медленнее на всех потоках Core i7 2600 на частоте 1,3 ГГц
  • Эльбрус 8СВ в 1,35 раза медленнее на всех потоках Core i7 2600 на частоте 1,55 ГГц

Во первых, для Python пока не делалось оптимизаций, которые повысили бы производительность. Во вторых, интерпретируемые языки плохо подходят к VLIW-архитектуре Эльбруса. Но МЦСТ советуют использовать CPython для производительности (Python -> C, а затем компилируем с помощью LCC). Про PyPy c Jit пока ничего не известно, но если потребуется, то такая среда выполнения будет реализована, а это сильно повысит производительность.


Также было замечено, что в некоторых случаях Python в режиме RTC (двоичная трансляция x86-64 в e2k) показывает большую производительность: в арифметике и математике. Значит есть ещё потенциал для оптимизации Python, возможно даже в 2 раза.


Бенчмарки Lua


Результаты бенчмарков на Lua

Результаты Lua на Эльбрусах в сравнении с Core i7 2600 3.4 ГГц:


  • Эльбрус 2С+ в 16 раз медленнее
  • Эльбрус 1С+ в 6 раз медленнее
  • Эльбрус 4С в 10 раз медленнее
  • Эльбрус 8С в 6 раз медленнее
  • Эльбрус 8СВ в 5 раз медленнее
  • Эльбрус R1000 в 9 раз медленнее

Результаты Lua на Эльбрусах в сравнении с Core i7 2600, но на одинаковых частотах:


  • Эльбрус 2С+ в 2,4 раза медленнее Core i7 2600 на частоте 0,5 ГГц
  • Эльбрус 1С+ в 1,75 раза медленнее Core i7 2600 на частоте 1 ГГц
  • Эльбрус 4С в 2 раза медленнее Core i7 2600 на частоте 0,8 ГГц
  • Эльбрус 8С в 2,3 раза медленнее Core i7 2600 на частоте 1,3 ГГц
  • Эльбрус 8СВ в 2,2 раза медленнее Core i7 2600 на частоте 1,55 ГГц
  • Эльбрус R1000 в 2,6 раз медленнее Core i7 2600 на частоте 1 ГГц

У Lua отставание всего в 2 раза на равных частотах, это достаточно тепримо для VLIW-архитектуры.


Выводы


Во сколько раз Core i7 2600 быстрее Эльбрусов:


Сводная таблица: во сколько раз Core i7 2600 быстрее Эльбрусов


Во сколько раз Core i7 2600 быстрее Эльбрусов, если бы он работал на частоте Эльбрусов:


Сводная таблица: во сколько раз Core i7 2600 быстрее Эльбрусов на одинаковой частоте


Как мы знаем, Эльбрус имеет VLIW архитектуру, у которой повышение производительности достигается путём оптимизации компилируемого кода (Эльбрус имеет явный параллелизм). Также у Эльбруса нет предсказателя переходов и переупорядочивания инструкций (снова всё явно задаётся компилятором).


Следует:


  • Компилируемые программы на C/C++ (возможно, другие) будут иметь хорошую производительность. Это достигается патчами участков кода, где нужно оптимизировать производительность и умным компилятором LCC (eLbrus C Compiler).
  • Языки с JIT-трансляцией (Java, JavaScript, C# Mono) будут иметь среднюю производительность. Здесь оптимизируют саму среду исполнения. Возможно, также потребуется оптимизировать сами программы.
  • Интерпретируемые языки (PHP, Python, Lua) будут иметь низкую производительность. Но оптимизация среды выполнения позволит поднять до среднего уровня.

Другие способы:


  • Доработка компилятора LCC.
  • Архитектурно-специфические доработки в самой ОС.
  • Улучшать архитектуру Эльбрус:
    • Поднимать частоту
    • Добавить предсказатель и т.д.

Какие языки ещё хотелсоь бы потестировать:


  • Golang (Ждём выпуска)
  • Ruby
  • Perl

P.S. Поздравляем команду МЦСТ с Новым Годом. Желаем удачи в разработке следующих поколений процессоров. Ждём массового появления устройств на процессорах с архитектурой E2K!


Другая интересная информация

"Что такое Эльбрус?


Эльбрус это полувековая история развития отечественной вычислительной технологии.
Это уникальная российская архитектура микропроцессора.
Это группа компаний объединенных одной идеей.
И наконец, это просто современный микропроцессор."
elbrus.ru


Web:


Официальный сайт: http://elbrus.ru


Официальная вики: http://wiki.community.elbrus.ru


Официальный форум: http://forum.community.elbrus.ru


Персональный сайт Максима Горшенина: http://imaxai.ru


Отличная вики на сайте ALT Linux Team: https://www.altlinux.org/Эльбрус


Telegram:


https://t.me/imaxairu основной канал с новостями из мира микропроцессоров Эльбрус из первых рук


https://t.me/e2k_chat на текущий момент основной чат по микропроцессорам Эльбрус, в котором можно пообщаться с разработчиками (организован сотрудниками компании Промобит, хорошо известной по продуктам BITBLAZE)


https://t.me/joinchat/FUktBxkwG8FKlhdzQ7DegQ чат для поболтать на разные темы любителями (и не очень) микропроцессоров Эльбрус с целью незасорения основного чата ненужной информацией, одним словом флудильня фан-клуба :)


Instagram:


Максим Горшенин и Эльбрусы: https://instagram.com/imaxai


Youtube:


Официальный канал группы компаний Elbrus: https://www.youtube.com/c/ElbrusTV


Частный канал Максима Горшенина: https://www.youtube.com/c/MaximGorshenin


Частный канал Михаила Захарова с эмз "Звезда": https://www.youtube.com/channel/UC3mtwuC2ugAngyO9tY2mqRw


Канал фанатов Е2К Elbrus PC Test (https://www.youtube.com/channel/UC4zlCBy0eFLkE-BxgqQK8FA):



Серия видеороликов по Эльбрусам от Дмитрия Бачило:



Серия видеороликов по играм на Эльбрусах от Дмитрия Пугачева:



Старенький, но не устаревающий ликбез по Эльбрусам Константина Трушкина на HighLoad++ 2014: https://youtu.be/ZTxOSGBCRec


Актуальными моделями микропроцессоров Эльбрус являются:



О существующих и будующих моделях микропроцессоров можно прочитать в вики Модели процессоров Эльбрус


Альта и оф. вики Характеристики процессоров Эльбрус


Результаты тестирования Результаты тестирования Эльбрус энтузиастами дают примерную оценку производительности. И это не предел, т.к. работы над совершенствованием оптимизирующего компилятора ведутся постоянно.


Попробовать ПК с процессором Эльбрус вживую можно в Яндекс.Музее в Москве.


Полезно прочитать:


Руководство по эффективному программированию на платформе Эльбрус http://mcst.ru/elbrus_prog Нейман-заде М. И., Королёв С. Д. 2020 [ PDF ] [ HTML ]


Микропроцессоры и вычислительные комплексы семейства Эльбрус (http://mcst.ru/files/511cea/886487/1a8f40/000000/book_elbrus.pdf) Ким А. К., Перекатов В. И., Ермаков С. Г. СПб.: Питер, 2013 272 с. ( PDF )


Операционные системы для архитектуры E2K:


АЛЬТ 8 СП (http://altsp.su/produkty/o-produktakh/) | Рабочая станция (https://www.basealt.ru/products/alt-workstation/) | Сервер (https://www.basealt.ru/products/alt-server/) | Образование (https://www.basealt.ru/products/alt-education/)


Astra Linux SE "Ленинград" (http://astralinux.ru/)


Эльбрус Линукс (http://mcst.ru/programmnoe-obespechenie-elbrus)


Попробовать ОС Эльбрус Линукс для x86_64:
https://yadi.sk/d/spqkqOAncT-aKQ
Документация:
https://yadi.sk/d/2shOcqIrmZQLLA


Интересное:


Вопрос:
Зачем VLIW, давай другую?


Ответ:


  1. http://www.mcst.ru/e2k_arch.shtml
  2. https://t.me/e2k_chat/89326

Лекция Бориса Бабаяна "История развития архитектуры вычислительных машин":
Часть 1 https://youtu.be/Swk27K9m_SA
Часть 2 https://youtu.be/QFD0NboTwTU

Подробнее..

Перевод Как я сократил время загрузки GTA Online на 70

01.03.2021 16:18:41 | Автор: admin
GTA Online. Многопользовательская игра, печально известная медленной загрузкой. Недавно я вернулся, чтобы завершить несколько ограблений и был потрясён, что она загружается настолько же медленно, как и в день своего выпуска, 7 лет назад.

Пришло время докопаться до сути.

Разведка


Сначала я хотел проверить, вдруг кто-то уже решил проблему. Но нашёл только рассказы о великой сложности игры, из-за чего она так долго загружается, истории о том, что сетевая p2p-архитектура мусор (хотя это не так), некоторые сложные способы загрузки в сюжетный режим, а потом в одиночную сессию, и ещё пару модов, чтобы скипнуть видео с логотипом R* во время загрузки. Ещё немного почитав форумы, я узнал, что можно сэкономить колоссальные 10-30 секунд, если использовать все эти способы вместе!

Тем временем на моём компе

Бенчмарк


Story mode load time:  ~1m 10sOnline mode load time: ~6m flatStartup menu disabled, time from R* logo until in-game (social club login time isn't counted).Old but decent CPU:   AMD FX-8350Cheap-o SSD:          KINGSTON SA400S37120GWe have to have RAM:  2x Kingston 8192 MB (DDR3-1337) 99U5471Good-ish GPU:         NVIDIA GeForce GTX 1070

Знаю, что моё железо устарело, но чёрт возьми, что может замедлить загрузку в 6 раз в онлайн-режиме? Я не мог измерить разницу при загрузке из сюжетного режима в онлайн, как это делали другие. Даже если это сработает, разница небольшая.

Я (не) одинок


Если доверять этому опросу, проблема достаточно широко распространена, чтобы слегка раздражать более 80% игроков. Прошло уже семь лет!



Я немного поискал информацию о тех ~20% счастливчиках, которые загружаются быстрее трёх минут, и нашёл несколько бенчмарков с топовыми игровыми ПК и временем загрузки онлайн-режима около двух минут. Я бы кого-нибудь убил хакнул за такой комп! Действительно похоже на железячную проблему, но что-то не складывается

Почему у них сюжетный режим по-прежнему загружается около минуты? (кстати, при загрузке с M.2 NVMe не учитывались видео с логотипами). Кроме того, загрузка из сюжетного режима в онлайн занимает у них всего минуту, в то время как у меня около пяти. Я знаю, что их железо гораздо лучше, но не в пять же раз.

Высокоточные измерения


Вооружившись таким мощным инструментом, как Диспетчер задач, я приступил к поиску узкого места.



Почти минута уходит на загрузку общих ресурсов, которые нужны и для сюжетного режима, и для онлайна (почти наравне с топовыми ПК), затем GTA в течение четырёх минут полностью нагружает одно ядро CPU, больше ничего не делая.

Использование диска? Нет! Использование сети? Есть немного, но через несколько секунд падает в основном до нуля (кроме загрузки вращающихся информационных баннеров). Использование GPU? Ноль. Память? Вообще ничего

Что это, майнинг биткоинов или что-то такое? Чую здесь код. Очень плохой код.

Единственный поток


На моём старом процессоре AMD восемь ядер, и он ещё молодцом, но это старая модель. Его сделали ещё тогда, когда производительность одного потока у AMD была намного ниже, чем у Intel. Наверное, это главная причина таких различий во времени загрузки.

Что странно, так это способ использования CPU. Я ожидал огромное количество операций чтения с диска или массу сетевых запросов, чтобы организовать сеансы в сети p2p. Но такое? Вероятно, здесь какая-то ошибка.

Профилирование


Профилировщик отличный способ найти узкие места в CPU. Есть только одна проблема большинство из них полагаются на инструментирование исходного кода, чтобы получить идеальную картину происходящего в процессе. А у меня нет исходного кода. Мне также не требуются идеальные показания в микросекундах, у меня узкое место на 4 минуты.

Итак, добро пожаловать в образцы стека (stack sampling). Для приложений с закрытым исходным кодом есть только такой вариант. Сбросьте стек запущенного процесса и местоположение указателя текущей инструкции, чтобы построить дерево вызовов в заданные интервалы. Затем наложите их и получите статистику о том, что происходит. Я знаю только один профилировщик, который может проделать это под Windows. И он не обновлялся уже более десяти лет. Это Люк Stackwalker! Кто-нибудь, пожалуйста, подарите Люку немножко любви :)



Обычно Люк группировал бы одинаковые функции, но у меня нет отладочных символов, поэтому пришлось смотреть на соседние адреса, чтобы искать общие места. И что же мы видим? Не одно, а целых два узких места!

Вниз по кроличьей норе


Позаимствовав у моего друга совершенно законную копию стандартного дизассемблера (нет, я действительно не могу его себе позволить когда-нибудь освою гидру), я пошёл разбирать GTA.



Выглядит совсем неправильно. Да, у большинства топовых игр есть встроенная защита от реверс-инжиниринга, чтобы защититься от пиратов, мошенников и моддеров. Не то чтобы это их когда-то останавливало

Похоже, здесь применили какую-то обфускацию/шифрование, заменив большинство инструкций тарабарщиной. Не волнуйтесь, нужно просто сбросить память игры, пока она выполняет ту часть, на которую мы хотим посмотреть. Инструкции должны быть деобфусцированы перед запуском тем или иным способом. У меня рядом лежал Process Dump, так что я взял его, но есть много других инструментов для подобных задач.

Проблема первая: это strlen?!


Дальнейший разбор дампа выявил один из адресов с некоей меткой strlen, которая откуда-то берётся! Спускаясь вниз по стеку вызовов, предыдущий адрес помечен как vscan_fn, и после этого метки заканчиваются, хотя я вполне уверен, что это sscanf.

Куда ж без графика

Он что-то парсит. Но что? Логический разбор займёт целую вечность, поэтому я решил сбросить некоторые образцы из запущенного процесса с помощью x64dbg. Через несколько шагов отладки выясняется, что это JSON! Он парсит JSON. Колоссальные десять мегабайт JSON'а с записями 63 тыс. предметов.

...,{    "key": "WP_WCT_TINT_21_t2_v9_n2",    "price": 45000,    "statName": "CHAR_KIT_FM_PURCHASE20",    "storageType": "BITFIELD",    "bitShift": 7,    "bitSize": 1,    "category": ["CATEGORY_WEAPON_MOD"]},...

Что это? Судя по некоторым ссылкам, это данные для сетевого торгового каталога. Предполагаю, он содержит список всех возможных предметов и обновлений, которые вы можете купить в GTA Online.

Проясним некоторую путаницу: я полагаю, что это предметы, приобретаемые за игровые деньги, не связанные напрямую с микротранзакциями.

10 мегабайт? В принципе, не так уж и много. Хотя sscanf используется не самым оптимальным образом, но, конечно, это не так уж плохо? Что ж



Да, такая процедура займёт некоторое время Честно говоря, я понятия не имел, что большинство реализаций sscanf вызывают strlen, поэтому не могу винить разработчика, который написал это. Я бы предположил, что он просто сканировал байт за байтом и мог остановиться на NULL.

Проблема вторая: давайте использовать хэш-массив?


Оказывается, второго преступника вызывают сразу за первым. Даже в одной и той же конструкции if, как видно из этой уродливой декомпиляции:



Все метки мои, и я понятия не имею, как на самом деле называются функции/параметры.

Вторая проблема? Сразу после разбора элемента он хранится в массиве (или встроенном списке C++? не уверен). Каждая запись выглядит примерно так:

struct {    uint64_t *hash;    item_t   *item;} entry;

А перед сохранением? Он проверяет весь массив, сравнивая хэш каждого элемента, есть он в списке или нет. С 63 тыс. записей это примерно (n^2+n)/2 = (63000^2+63000)/2 = 1984531500, если я не ошибаюсь в расчётах. И это в основном бесполезные проверки. У вас есть уникальные хэши, почему не использовать хэш-карту.



Во время реверс-инжиниринга я назвал его hashmap, но это явно не_hashmap. И дальше ещё интереснее. Этот хэш-массив-список пуст перед загрузкой JSON. И все элементы в JSON уникальны! Им даже не нужно проверять, есть они в списке или нет! У них даже есть функция прямой вставки элементов! Просто используйте её! Серьёзно, ну ребята, что за фигня!?

PoC


Всё это конечно классно, но никто не воспримет меня всерьёз, пока я не напишу реальный код для ускорения загрузки, чтобы сделать кликбейтный заголовок для поста.

План такой. 1. Написать .dll, 2. внедрить её в GTA, 3. зацепить некоторые функции, 4. ???, 5. профит. Всё предельно просто.

Проблема с JSON нетривиальная, я не могу реально заменить их парсер. Более реалистичным кажется заменить sscanf на тот, который не зависит от strlen. Но есть ещё более простой способ.

  • зацепить strlen
  • подождать длинной строки
  • закэшировать начало и длину
  • если поступит ещё вызов в пределах диапазона строки, вернуть закэшированное значение

Что-то вроде такого:

size_t strlen_cacher(char* str){  static char* start;  static char* end;  size_t len;  const size_t cap = 20000;  // if we have a "cached" string and current pointer is within it  if (start && str >= start && str <= end) {    // calculate the new strlen    len = end - str;    // if we're near the end, unload self    // we don't want to mess something else up    if (len < cap / 2)      MH_DisableHook((LPVOID)strlen_addr);    // super-fast return!    return len;  }  // count the actual length  // we need at least one measurement of the large JSON  // or normal strlen for other strings  len = builtin_strlen(str);  // if it was the really long string  // save it's start and end addresses  if (len > cap) {    start = str;    end = str + len;  }  // slow, boring return  return len;}


А что касается проблемы хэш-массива, то здесь просто полностью пропускаем все проверки и вставляем элементы напрямую, поскольку мы знаем, что значения уникальны.

char __fastcall netcat_insert_dedupe_hooked(uint64_t catalog, uint64_t* key, uint64_t* item){  // didn't bother reversing the structure  uint64_t not_a_hashmap = catalog + 88;  // no idea what this does, but repeat what the original did  if (!(*(uint8_t(__fastcall**)(uint64_t*))(*item + 48))(item))    return 0;  // insert directly  netcat_insert_direct(not_a_hashmap, key, &item);  // remove hooks when the last item's hash is hit  // and unload the .dll, we are done here :)  if (*key == 0x7FFFD6BE) {    MH_DisableHook((LPVOID)netcat_insert_dedupe_addr);    unload();  }  return 1;}

Полный исходный код PoC здесь.

Результаты


Ну и как оно работает?

Original online mode load time:        ~6m flatTime with only duplication check patch: 4m 30sTime with only JSON parser patch:       2m 50sTime with both issues patched:          1m 50s(6*60 - (1*60+50)) / (6*60) = 69.4% load time improvement (nice!)

Да, чёрт возьми, получилось! :))

Скорее всего, это не решит всех проблем с загрузкой в разных системах могут быть и другие узкие места, но это такая зияющая дыра, что я понятия не имею, как R* пропустила её за все эти годы.

Краткое содержание


  • При запуске GTA Online есть узкое место, связанное с однопоточным вычислением
  • Оказалось, GTA изо всех сил пытается распарсить 1-мегабайтный файл JSON
  • Сам парсер JSON плохо сделан/наивен и
  • После парсинга происходит медленная процедура удаления дублей

R*, пожалуйста, исправьте


Если информация каким-то образом дойдёт до инженеров Rockstar, то проблему можно решить в течение нескольких часов силами одного разработчика. Пожалуйста, ребята, сделайте что-нибудь с этим :<

Вы можете либо перейти на хэш-карту для удаления дублей, либо полностью пропустить дедупликацию при запуске как быстрое исправление. Для парсера JSON просто замените библиотеку на более производительную. Не думаю, что есть более простой вариант.

ty <3
Подробнее..

Бенчмарки VKUI и других ребят из UI-библиотек

26.05.2021 12:10:08 | Автор: admin

Меня зовут Григорий Горбовской, я работаю в Web-команде департамента по экосистемным продуктам ВКонтакте, занимаюсь разработкой VKUI.

Хочу вкратце рассказать, как мы написали 8 тестовых веб-приложений, подключили их к моно-репозиторию, автоматизировали аудит через Google Lighthouse с помощью GitHub Actions и как решали проблемы, с которыми столкнулись.

VKUI это полноценный UI-фреймворк, с помощью которого можно создавать интерфейсы, внешне неотличимые от тех, которые пользователь видит ВКонтакте. Он адаптивный, а это значит, что приложение на нём будет выглядеть хорошо как на смартфонах с iOS или Android, так и на больших экранах планшетах и даже десктопе. Сегодня VKUI используется практически во всех сервисах платформы VK Mini Apps и важных разделах приложения ВКонтакте, которые надо быстро обновлять независимо от магазинов.

VKUI также активно применяется для экранов универсального приложения VK для iPhone и iPad. Это крупное обновление с поддержкой планшетов на iPadOS мы представили 1 апреля.

Адаптивный экран на VKUIАдаптивный экран на VKUI

Масштабирование было внушительным поэтому мы провели аудит, проанализировали проблемы, которые могут возникнуть у нас и пользователей при работе с VKUI, и заодно сравнили свои решения с продуктами ближайших конкурентов.

Какие задачи поставили

  1. Выявить главные проблемы производительности VKUI.

  2. Подготовить почву, чтобы развернуть автоматизированные бенчмарки библиотеки и наших веб-приложений на основеVKUI.

  3. Сравнить производительность VKUI и конкурирующих UI-фреймворков.

Технологический стек

Инструменты для организации процессов:

Чтобы проще взаимодействовать с несколькими веб-приложениями, в которых применяются разные UI-библиотеки, здесь используем lerna. Это удобный инструмент, с помощью которого мы объединили в большой проект ряд приложений с отличающимися зависимостями.

Бенчмарки мы проводим через Google Lighthouse официальный инструмент для измерения Web Vitals. Де-факто это стандарт индустрии для оценки производительности в вебе.

Самое важное делает GitHub Actions: связывает воедино сборку и аудит наших приложений.

Библиотеки, взятые для сравнения:

Название

Сайт или репозиторий

VKUI

github.com/VKCOM/VKUI

Material-UI

material-ui.com

Yandex UI

github.com/bem/yandex-ui

Fluent UI

github.com/microsoft/fluentui

Lightning

react.lightningdesignsystem.com

Adobe Spectrum

react-spectrum.adobe.com

Ant Design

ant.design

Framework7

framework7.io


Мы решили сравнить популярные UI-фреймворки, часть из которых основана на собственных дизайн-системах. В качестве базового шаблона на React использовали create-react-app, и на момент написания приложений брали самые актуальные версии библиотек.

Тестируемые приложения

Первым делом мы набросали 8 приложений. В каждом были такие страницы:

  1. Default страница с адаптивной вёрсткой, содержит по 23 подстраницы.

    • На главной находится лента с однотипным контентом и предложением ввести код подтверждения (абстрактный). При его вводе на несколько секунд отображается полноэкранный спиннер загрузки.

    • Страница настроек, в которую входит модальное окно с примитивным редактированием профиля и очередным предложением ввести код.

    • Страница с простым диалогом условно, с техподдержкой.

  2. List (Burn) страница со списком из 500 элементов. Главный аспект, который нам хотелось проверить: как вложенность кликабельных элементов влияет на показатель Performance.

  3. Modals страница с несколькими модальными окнами.

Не у всех UI-фреймворков есть аналогичные компоненты недостающие мы заменяли на равнозначные им по функциональности. Ближе всего к VKUI по компонентам и видам их отображения оказались Material-UI и Framework7.

Сделать 8 таких приложений поначалу кажется простой задачей, но спустя неделю просто упарываешься писать одно и то же, но с разными библиотеками. У каждого UI-фреймворка своя документация, API и особенности. С некоторыми я сталкивался впервые. Особенно запомнился Yandex UI кажется, совсем не предназначенный для использования сторонними разработчиками. Какие-то компоненты и описания параметров к ним удавалось найти, только копаясь в исходном коде. Ещё умилительно было обнаружить в компоненте хедера логотип Яндекса <3

Вернёмся к нашим приложениям. Когда были написаны первые три, мы начали параллельную работу над автоматизацией аудита:

Автоматизация

Краткая блок-схема, описывающая процессы в автоматизацииКраткая блок-схема, описывающая процессы в автоматизации

Подготовили два воркфлоу:

  • Build and Deploy здесь в первую очередь автоматизировали процессы сборки и разворачивания. Используем surge, чтобы быстро публиковать статичные приложения. Но постепенно перейдём к их запуску и аудиту внутри GitHub Actions воркеров.

  • Run Benchmarks а здесь создаётся issue-тикет в репозитории со ссылкой на активный воркфлоу, затем запускается Lighthouse CI Action по подготовленным ссылкам.

UI-фреймворк

URL на тестовое приложение

VKUI

vkui-benchmark.surge.sh

Ant Design

ant-benchmark.surge.sh

Material UI

mui-benchmark.surge.sh

Framework7

f7-benchmark.surge.sh

Fluent UI

fluent-benchmark.surge.sh

Lightning

lightning-benchmark.surge.sh

Yandex UI

yandex-benchmark.surge.sh

Adobe Spectrum

spectrum-benchmark.surge.sh


Конфигурация сейчас выглядит так:

{  "ci": {    "collect": {      "settings": {        "preset": "desktop", // Desktop-пресет        "maxWaitForFcp": 60000 // Время ожидания ответа от сервера      }    }  }}

После аудита всех приложений запускается задача finalize-report. Она форматирует полученные данные в удобную сравнительную таблицу (с помощью магии Markdown) и отправляет её комментарием к тикету. Удобненько, да?

Пример подобного репорта от 30 марта 2021 г.Пример подобного репорта от 30 марта 2021 г.

Нестабильность результатов

На начальных стадиях мы столкнулись с нестабильностью результатов: в разных отчётах наблюдали сильную просадку баллов, причём всегда у разных приложений.

Из отчётов Lighthouse выяснили следующее: по неведомым причинам сервер долго отвечал, и это привело к общему замедлению и снижению баллов. Изначально грешили на воркеры и хостинг в целом, и я решился задеплоить и провести бенчмарки на одном сервере. Результаты стали лучше, но такое странное поведение оставалось нелогичным.

Предупреждения из отчётов Google LighthouseПредупреждения из отчётов Google Lighthouse

GitHub Actions по умолчанию выполняет задачи параллельно, как и в нашем воркфлоу с бенчмарками. Решение ограничить максимальное количество выполняющихся одновременно задач:

jobs.<job_id>.strategy.max-parallel: 1

Мы провели бенчмарк дважды, и вуаля результаты стали ощутимо стабильнее. Теперь можно переходить к результатам.

Результаты от 30 марта 2021 г.

VKUI (4.3.0) vs ant:

app

type (app link)

report

performance

vkui (4.3.0)

default

report

0.99

ant

default

report

0.99

vkui (4.3.0)

modals

report

1

ant

modals

report

0.99

vkui (4.3.0)

list

report

0.94

ant

list

report

0.89

list - У ant нет схожего по сложности компонента для отрисовки сложных списков, но на 0,05 балла отстали.

VKUI (4.3.0) vs Framework7:

app

type (app link)

report

performance

vkui (4.3.0)

default

report

0.99

f7

default

report

0.98

vkui (4.3.0)

modals

report

1

f7

modals

report

0.99

vkui (4.3.0)

list

report

0.94

f7

list

report

0.92

list - Framework7 не позволяет вложить одновременно checkbox и radio в компонент списка (List).

VKUI (4.3.0) vs Fluent:

app

type (app link)

report

performance

vkui (4.3.0)

default

report

0.99

fluent

default

report

0.94

vkui (4.3.0)

modals

report

1

fluent

modals

report

0.99

vkui (4.3.0)

list

report

0.94

fluent

list

report

0.97

modals - Разница на уровне погрешности.

list - Fluent не имеет схожего по сложности компонента для отрисовки сложных списков.

VKUI (4.3.0) vs Lightning:

app

type (app link)

report

performance

vkui (4.3.0)

default

report

0.99

lightning

default

report

0.95

vkui (4.3.0)

modals

report

1

lightning

modals

report

1

vkui (4.3.0)

list

report

0.94

lightning

list

report

0.99

list - Lightning не имеет схожего по сложности компонента для отрисовки сложных списков.

VKUI (4.3.0) vs mui:

app

type (app link)

report

performance

vkui (4.3.0)

default

report

0.99

mui

default

report

0.93

vkui (4.3.0)

modals

report

1

mui

modals

report

0.96

vkui (4.3.0)

list

report

0.94

mui

list

report

0.77

default и modals - Расхождение незначительное, у Material-UI проседает First Contentful Paint.

list - При примерно одинаковой загруженности списков в Material-UI и VKUI выигрываем по Average Render Time почти в три раза (~1328,6 мс в Material-UI vs ~476,4 мс в VKUI).

VKUI (4.3.0) vs spectrum:

app

type (app link)

report

performance

vkui (4.3.0)

default

report

0.99

spectrum

default

report

0.99

vkui (4.3.0)

modals

report

1

spectrum

modals

report

1

vkui (4.3.0)

list

report

0.94

spectrum

list

report

1

list - Spectrum не имеет схожего по сложности компонента для отрисовки сложных списков.

VKUI (4.3.0) vs yandex:

app

type (app link)

report

performance

vkui (4.3.0)

default

report

0.99

yandex

default

report

1

vkui (4.3.0)

modals

report

1

yandex

modals

report

1

vkui (4.3.0)

list

report

0.94

yandex

list

report

1

default - Разница на уровне погрешности.

list - Yandex-UI не имеет схожего по сложности компонента для отрисовки сложных списков.

modals - Модальные страницы в Yandex UI объективно легче.

Выводы из отчёта Lighthouse о VKUI

  • VKUI по показателям на одном уровне с другими библиотеками. Сильных просадок, как и значительного превосходства, нет.

  • Одно из явных проблемных мест вложенные Tappable протестированы на большом списке. Единственная библиотека, в которой полноценно реализован этот кейс, Material-UI. И VKUI уверенно обходит её по производительности.

  • Lighthouse ругается на стили после сборки много неиспользуемых. Они же замедляют First Contentful Paint. Над этим уже работают.

Два CSS-чанка, один из которых весит 27,6 кибибайт без сжатия в gzДва CSS-чанка, один из которых весит 27,6 кибибайт без сжатия в gz

Планы на будущее vkui-benchmarks

Переход с хостинга статики на локальное тестирование должен сократить погрешность: уменьшится вероятность того, что из-за внешнего фактора станет ниже балл у того или иного веб-приложения. Ещё у нас в репортах есть показатель CPU/Memory Power и он немного отличается в зависимости от воркеров, которые может дать GitHub. Из-за этого результаты в репортах могут разниться в пределах 0,010,03. Это можно решить введением перцентилей.

Также планируем сделать Lighthouse Server для сохранения статистики по бенчмаркам на каждый релиз.

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru