Большей части населения РФ требуется не только игра, но и её перевод на русский язык. После ввода ограничений количество игр на русском языке будет стремиться к нулю.
Вспомнил, что в c# есть Span<T>.Fill. Для C использовал компилятор clang-19.1.0 с аргументом "-O3". Результат, абсолютно одинаковая скорость. Так что выводы в статье абсолютно неверные, как и код для тестирования.
Похоже что так и есть. Chatgpt говорит, что: memset относится к языку C как часть стандартной библиотеки, но её оптимизация зависит от компилятора и библиотеки, связанной с ОС.
Без SIMD такой буст как в тестах в статье просто невозможен.
Ваш код проверил, цифры те же +- что и у обычного массива.
Насчёт этого не понял. Этот код с Vector256 ну просто не может быть по скорости таким же как как ваш из статьи.
upd: не заметил, что вы написали в комментарии скомпилированный код C, а не c#. На C я не работал. Поэтому подумал, что там есть SIMD инструкции после компиляции и не проверил свою гипотезу.
Не стал упоминать Vector512 иначе бы пришлось этот маленький пример превратить в простыню из:
if (Vector512.IsHardwareAccelerated) {}
else if (Vector256.IsHardwareAccelerated) {}
else if (Vector128.IsHardwareAccelerated) {}
else if (Vector64.IsHardwareAccelerated) {}
else {}
Но это всё не имеет значения в контексте этого теста. Да и моё железо не поддерживает Vector512.
Компилятор C активно использует SIMD инструкции. А в вашем коде c# таких инструкций нет. Перепишите код с использованием Vector128/Vector256 и повторите тест. А то как-то нечестно получилось.
unsafe
{
const int typicalItarationsCount = 10;
const int arraySize = 1073741824;
var lineLength = sizeof(Vector256<byte>);
var linesCount = arraySize / lineLength;
var tmpArray = new byte[arraySize];
for (var iteration = 0; iteration < typicalItarationsCount; ++iteration)
{
var watch = new Stopwatch();
watch.Start();
fixed (byte* tmpArrayPtr = tmpArray)
for (long i = 0; i < linesCount; ++i)
{
var vector = Vector256.Create((byte) 1);
vector.Store(tmpArrayPtr + i * lineLength);
}
watch.Stop();
tmpArray = new byte[arraySize];
Console.WriteLine($"iter={iteration} seq time={watch.ElapsedMilliseconds}");
}
}
Примерно так это выглядит на моём пк. Цифры не идеальны т.к. в фоне работает много процессов. Я не ставил целью сделать идеальный тест. Лишь хотел показать тенденцию.
Мой код с Vector256
Код из статьи
Если сравнивать C и c#, то только так. У меня нет настроенного рабочего окружения под C чтобы проверить разницу с шарпом. Оставляю это для вас.
На размер билда это никак не влияет. Абсолютно любой формат изображения попадёт в билд как текстура определённого формата, выбранного в зависимости от платформы. Т.е. любой png/psd/jpg будет конвертирован в какой-нибудь BC7. И финальный размер текстуры будет зависеть от настроек импорта, а не от формата исходного изображения.
Самым известным является то, что движок Unity использует только один поток обработки информации при работе с процессором.
Если unity работает только в одном потоке, то как я сделал этот скриншот профайлера, где видно, что загружены все ядра процессора?
Автор статьи вообще знает о юнити хоть что-то кроме домыслов сделанных на основе даже не знаю чего? Вопрос риторический.
За последние годы в unity проделана огромная работа, делающая движок многопоточным. Есть шикарный инструментарий для программистов Job system. Есть компилятор burst который выдаёт производительность в 10-20 раз большую чем il2cpp и сравним по скорости с нативным плюсовым кодом. Нативные библиотеки такие как физика, система частиц, звук используют дополнительные потоки для своих вычислений. В 23 версии появился Awaitable. А использовать родные Thread никто никогда не запрещал. В каждой новой версии юнити появляется всё большее количество апи которые позволяют работать с движком вне основного потока. Но автор с абсолютной уверенностью пишет, что unity это однопоточный движок, который не умеет в мультипоточность. И эта статья заплюсована.
Просто к сведенью. Видеокарта не работает с png от слова совсем. Браузер каждую png распаковывает в битмап. 1024x760 RGBA8 UNorm это 3.0 MB. На некоторых мобильных устройствах размер текстуры будет изменён до квадрата двойки по большей стороне. Т.е. станет 1024x1024 4.0 MB. А сжатая текстура будет весить 0.7 MB в ETC2 и отправляется в память видеокарты как есть. Но сжатые текстуры придётся делать в разных форматах под разные платформы. В идеале этим должен заниматься движок на котором делается игра.
Ваша демка, что на i7-7700, что на Snapdragon 835 при попытке зума уходит в загрузку на 30 секунд. Я, конечно, не эксперт, но с такими таймингами тут оптимизацией даже не пахнет. И там, и там Chrome последней версии.
2-3 фпс при таком масштабе и погрузка около минуты если сдвинуть карту хоть немного.
Откуда вообще берутся такие юзеры на хабре. И кто-то плюсует комментарий.
Под рукой в данный момент открытая unity. Создал простейший шейдер, который берет uv координаты и выводит x. Т.е. на выходе линейное изменение от 0 до 1. Но вообще такое даже проверять глупо. Всё равно, что подвергать сомнению высказывание "земля круглая".
Результат
Шейдер
Скрин того, что лежит в uv. Чтобы не было сомнений.
Результаты тестирования unsafe методов абсолютно неверны, потому что сами методы написаны неправильно. Закрепление объекта внутри цикла так себе идея, fixed нужно вынести на уровень выше.
public unsafe string Unsafe_ReadOnlySpan_NewString()
{
ReadOnlySpan<char> chars = Content.AsSpan();
fixed (char* baseChar = chars)
for (int i = 0; i < chars.Length; i++)
{
if (baseChar[i] == ' ') baseChar[i] = ',';
}
return new string(chars);
}
Структурные буферы поддерживаются на всех платформах и для всех графических апи. Для доступа к ним из вершинного шейдера нужна Shader Mode 5.0 и выше. Единственное исключение это мобильники из низкого ценового сегмента, работающие на OpenGL ES 2.0.
Сменить пайплайн с built-in на URP. SRP-batcher даёт очень сильный буст при использовании разных мешей с одинаковым шейдером.
Отказаться от GameObject и использовать CommandBuffer для отрисовки объектов.
Отказаться от хранения данных в текстуре. Эпоха dx9 давно ушла. Используете structured buffer.
Переход на структурные буферы открывает возможность хорошо перепаковать данные. Вместо 4 каналов png по 8 бит, вы можете использовать структуры любой сложности. С помощью квантизации разместить их максимально компактно. По ссылке пример упаковки данных для сетевой передачи, для видеокарты это конечно же не подходит. Упаковать данные можно лишь в пределах одного элемента структуры. Но принцип тот же.
Попробуйте добавить атрибут [SkipLocalsInit], чтобы избежать постоянной инициализации нулями span'ов. Должно стать быстрее.
Большей части населения РФ требуется не только игра, но и её перевод на русский язык. После ввода ограничений количество игр на русском языке будет стремиться к нулю.
Вспомнил, что в c# есть Span<T>.Fill. Для C использовал компилятор clang-19.1.0 с аргументом "-O3". Результат, абсолютно одинаковая скорость. Так что выводы в статье абсолютно неверные, как и код для тестирования.
Похоже что так и есть. Chatgpt говорит, что:
memset
относится к языку C как часть стандартной библиотеки, но её оптимизация зависит от компилятора и библиотеки, связанной с ОС.Без SIMD такой буст как в тестах в статье просто невозможен.
Отметил на скрине avx инструкции.
Можно здесь посмотреть. https://sharplab.io/
Насчёт этого не понял. Этот код с Vector256 ну просто не может быть по скорости таким же как как ваш из статьи.
upd: не заметил, что вы написали в комментарии скомпилированный код C, а не c#. На C я не работал. Поэтому подумал, что там есть SIMD инструкции после компиляции и не проверил свою гипотезу.
Не стал упоминать Vector512 иначе бы пришлось этот маленький пример превратить в простыню из:
Но это всё не имеет значения в контексте этого теста. Да и моё железо не поддерживает Vector512.
Компилятор C активно использует SIMD инструкции. А в вашем коде c# таких инструкций нет. Перепишите код с использованием Vector128/Vector256 и повторите тест. А то как-то нечестно получилось.
Примерно так это выглядит на моём пк. Цифры не идеальны т.к. в фоне работает много процессов. Я не ставил целью сделать идеальный тест. Лишь хотел показать тенденцию.
Если сравнивать C и c#, то только так. У меня нет настроенного рабочего окружения под C чтобы проверить разницу с шарпом. Оставляю это для вас.
В превью статьи ещё осталось "капнуть".
На размер билда это никак не влияет. Абсолютно любой формат изображения попадёт в билд как текстура определённого формата, выбранного в зависимости от платформы. Т.е. любой png/psd/jpg будет конвертирован в какой-нибудь BC7. И финальный размер текстуры будет зависеть от настроек импорта, а не от формата исходного изображения.
Ещё PotPlayer отличная штука.
Зачем размещать статью в хабе Unity, если внутри статьи нет ни слова о Unity?
Если unity работает только в одном потоке, то как я сделал этот скриншот профайлера, где видно, что загружены все ядра процессора?
Автор статьи вообще знает о юнити хоть что-то кроме домыслов сделанных на основе даже не знаю чего? Вопрос риторический.
За последние годы в unity проделана огромная работа, делающая движок многопоточным. Есть шикарный инструментарий для программистов Job system. Есть компилятор burst который выдаёт производительность в 10-20 раз большую чем il2cpp и сравним по скорости с нативным плюсовым кодом. Нативные библиотеки такие как физика, система частиц, звук используют дополнительные потоки для своих вычислений. В 23 версии появился Awaitable. А использовать родные Thread никто никогда не запрещал. В каждой новой версии юнити появляется всё большее количество апи которые позволяют работать с движком вне основного потока. Но автор с абсолютной уверенностью пишет, что unity это однопоточный движок, который не умеет в мультипоточность. И эта статья заплюсована.
Job system и burst вышли из чата.
Просто к сведенью. Видеокарта не работает с png от слова совсем. Браузер каждую png распаковывает в битмап. 1024x760 RGBA8 UNorm это 3.0 MB. На некоторых мобильных устройствах размер текстуры будет изменён до квадрата двойки по большей стороне. Т.е. станет 1024x1024 4.0 MB. А сжатая текстура будет весить 0.7 MB в ETC2 и отправляется в память видеокарты как есть. Но сжатые текстуры придётся делать в разных форматах под разные платформы. В идеале этим должен заниматься движок на котором делается игра.
Ваша демка, что на i7-7700, что на Snapdragon 835 при попытке зума уходит в загрузку на 30 секунд. Я, конечно, не эксперт, но с такими таймингами тут оптимизацией даже не пахнет. И там, и там Chrome последней версии.
Только не рассказывайте автору статьи про RaycastCommand в Unity. А то он совсем в депрессию впадёт.
Откуда вообще берутся такие юзеры на хабре. И кто-то плюсует комментарий.
Под рукой в данный момент открытая unity. Создал простейший шейдер, который берет uv координаты и выводит x. Т.е. на выходе линейное изменение от 0 до 1. Но вообще такое даже проверять глупо. Всё равно, что подвергать сомнению высказывание "земля круглая".
А вот с гамма-коррекцией:
Результаты тестирования unsafe методов абсолютно неверны, потому что сами методы написаны неправильно. Закрепление объекта внутри цикла так себе идея, fixed нужно вынести на уровень выше.
Структурные буферы поддерживаются на всех платформах и для всех графических апи. Для доступа к ним из вершинного шейдера нужна Shader Mode 5.0 и выше. Единственное исключение это мобильники из низкого ценового сегмента, работающие на OpenGL ES 2.0.
Что можно сделать ещё, чего я не увидел в статье.
Сменить пайплайн с built-in на URP. SRP-batcher даёт очень сильный буст при использовании разных мешей с одинаковым шейдером.
Отказаться от GameObject и использовать CommandBuffer для отрисовки объектов.
Отказаться от хранения данных в текстуре. Эпоха dx9 давно ушла. Используете structured buffer.
Переход на структурные буферы открывает возможность хорошо перепаковать данные. Вместо 4 каналов png по 8 бит, вы можете использовать структуры любой сложности. С помощью квантизации разместить их максимально компактно. По ссылке пример упаковки данных для сетевой передачи, для видеокарты это конечно же не подходит. Упаковать данные можно лишь в пределах одного элемента структуры. Но принцип тот же.
Файлы с данными можно запаковать с помощью Deflate или GZip.