Comments 7
классно, блики идут от солнца и взгляда взависимости от дальности наблюдателя, и антиблики это прозрачность с затенением (если ниже есть обьём), тогда можно обойтись 2 синусоидами(это частичный фурье без поворота как я понял) и меньшим размером кусочка(морф поверхности) - он будет в размерах мировых в метрике, который можно клонировать и масштабировать(тоже ейсролу смотрел, резкие волны просто не понравились и тут я свернул в другую сторону )) резкие волны обыграл брауновским движением(бурлением микро дисторшн) в морфе
к морфу подходил через морф сферы, а потом этот же морф стал применять к сетке(плоскости из НхН квадратов(2треугольника)) и далее по дельте подбирал фазу
Средств выразительности языка вполне хватило для осуществления этого проекта.
Оно конечно хорошо, но киллер-фичей пока не замечено, учитывая большую вербозность языка в сравнении с тем же C++.
Производительность тоже весьма неплоха — на уровне других компилируемых языков, вроде C++
Вот тут press X doubt
. Производительность скорее на уровне, который позволяет наоптимизировать LLVM из того наивного IR, который делает U. Да и снижение производительности на 10 процентов означает, что проверка границ происходит не при помощи инвариантов типа (как в том же Rust), которые выоптимизировываются, а наивными проверками.
киллер-фичей пока не замечено,
В Ü его главное преимущество - безопасность работы с памятью (если не стрелять в ногу с unsafe). Но в этом проекте да, оно не так чтобы сильно заметно, ибо в целом то код достаточно простой.
Производительность скорее на уровне, который позволяет наоптимизировать LLVM из того наивного IR, который делает U.
Так и в C++ так же. Фронтенд clang генерирует тоже весьма неоптимизированный IR код, ускорением которого и занимается библиотека LLVM. Взгляните на каком-нибудь godbolt, какой IR clang выдаёт (с опцией -emit-llvm).
проверка границ происходит не при помощи инвариантов типа (как в том же Rust)
Что за проверка через инвариант типа? Можете пояснить?
В Ü проверки границ выполняются вообще говоря не в каждом обращении к элементу массива. Они используются, только если обращаться к произвольному индексу через оператор []
. Но вот если происходит последовательная (или обратная) итерация по элементам, проверок не производится.
В коде описанного в этой статье проекта подобных (почти) случайных обращений по индексу просто весьма много - для быстрого обратного преобразования Фурье, сдвигов карты высот, вычисления нормалей и т. д. Отсюда и наблюдаемое небольшое замедление в сравнении со случаем, когда проверки границ отключены. Но могут быть программы, где массивы в основном только последовательно перебираются, в таком случае нет проверок и замедления.
Фронтенд clang генерирует тоже весьма неоптимизированный IR код
Там довольно немало подсказок имеется касательно данных, позволяя делать иногда не самые очевидные оптимизации - где-то автовекторизация срабатывает, где-то constexpr вычисляется, где-то память остаётся на месте (move семантика и return value optimization). Не знаю насколько это поддеживается в U, но с большой долей вероятности их может и не оказаться.
только если обращаться к произвольному индексу через оператор
[]
.
ну вот по крайней мере в Rust если точно известно, что индекс никогда не превысит размер массива, то он вроде осиливает убрать проверку границ. Что-то вроде
let mut vec= Vec::with_capacity(sz);
/*
...
массив как-то заполняется до sz
...
*/
for i in 0..sz {
...
let blabla = vec[i]; // граница проверяется ровно
// 1 раз при входе в массив
...
}
Но собственно идею с инвариантами вы поняли - ограничения типов позволяют статически проверять все эти границы и динамически проверок уже не требуется. Обычно такого рода штуки проверяются со стороны фронтенда.
Я могу конечно ошибаться и U всё это могёт умеет, но и изначальный комментарий это скорее камень в ваш огород кастательно сравнения перформанса "на дцать процентов" на глазок без бенчмарок.
пардон, веткой промахнулся.
Там довольно немало подсказок имеется касательно данных
В Ü я тоже такое местами делаю. Это включает nonnull metadata, lifetimes, type-based alias analysis, dereferenceable атрибуты и прочее.
ну вот по крайней мере в Rust если точно известно, что индекс никогда не превысит размер массива, то он вроде осиливает убрать проверку границ
В Ü такое есть, но только для встроенных массивов (с размером, известным на этапе сборки) и с индексом, известным на этапе сборки.
Что-то вроде
Тут надо смотреть, кто проводит анализ диапазонов индекса - фронтенд или бекенд. Вполне возможно, что LLVM что-то подобное тоже может оптимизировать и убрать проверки.
"на дцать процентов" на глазок без бенчмарок.
Это да. Каюсь, грешен. Я провёл эксперимент с отключением проверки границ в самый последний момент, чтобы чисто посмотреть, что какой-то эффект заметен. Он заметен, но не сильно, посему я дальше в эту сторону капать не стал.
С трудом оживил ассоциацию с названием языка - Knorkator - "Buchstabe" =)
Какая то помесь crust, надо вчитаться
Пишем симуляцию океанских волн на языке программирования Ü