Pull to refresh

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 что-то подобное тоже может оптимизировать и убрать проверки.

"на дцать процентов" на глазок без бенчмарок.

Это да. Каюсь, грешен. Я провёл эксперимент с отключением проверки границ в самый последний момент, чтобы чисто посмотреть, что какой-то эффект заметен. Он заметен, но не сильно, посему я дальше в эту сторону капать не стал.

Для полного счастья не хватает Ü в compiler explorer.

С трудом оживил ассоциацию с названием языка - Knorkator - "Buchstabe" =)

Какая то помесь crust, надо вчитаться

Sign up to leave a comment.

Articles