не перестаю восхищаться лектором и аудиторией. жаль что нет возможности на одинаковом уровне громкости слышать как лектора так и аудиторию. какждый ваш выпуск для меня настоящий праздник. доброго здоровья вам и вашим близким как лектору так и аудитории
По поводу кастинга - я понимаю почему кастинг не будет работать в случае кастинга в сторону не char. Т.к. он формирует выходные данные с учётом репрезентации типа. Но помимо char* существует ещё и void* который гарантирует что репрезентация будет исходной. Я бы прости приводил к void* и затем к dst.
на тему извлечения битов: верно ли что union {float f; unsigned u;} это по сути тот же каст адреса и то же уб? И может ли в теории возникнуть ситуация, где каст/юнион и memcpy дадут разный результат?
Нет это т.н. type punning. У него более спорный статус. Его то запрещают то разрешают. Лучше им не пользоваться никогда. Но это не имеет отношения к strict aliasing.
Можно ли для получения битов float в int использовать reinterpret_cast вместо memcpy? Без указателей, просто интерпретировать значение. Если нет, то почему?
Константин, я не думал, что мне придётся это Вам пояснять. Но Ваше утверждение на лекции звучит, так - "Все трансцендентные числа - вычислимы", вот это утверждение неверно. Я не спорю с тем, что некоторые трансцендентные числа - вычислимы. Но я утверждаю, что почти все трансцендентные числа - не вычислимы.
@@КарлГаусс-ъ2и я не думал что меня именно так можно понять. Я разумеется имел в виду ту небольшую часть трансцендентных чисел которые тоже вычислимы.
А почему не используют1-байтовые float, разработчики железа, почему не делают такой функционал на cpu gpu? К примеру для расчета цвета пикселей c simd. Ведь по факту точность для 256 значений не важна в многих случаях.
А почему бы для пикселей не использовать однобайтовые целые? Там где короткие floating point числа обоснованы -- в нейросетях например -- их делают. Всякие там bfloat16 и всё такое. Но серьёзное обоснование именно для восьми бит с плавающей точкой (а сколько на мантиссу?) мне не встречалось.
@@tilir как раз в AI сейчас модно не только 8-bit float (2 вида, s1e4m3 и s1e5m2), но даже и 4-bit float (s1e2m1). Но за пределами AI они не очень-то применимы.
Разве не около ±1-цы наибольшая плотность чисел т.к. экспонента минимальна. А промежуток между -float_min и +float_min вообще выпадает, кроме нуля(ну это исключение). Либо около min всё таки?
@@tilir Как раз про денормализованные числа речь. format | MINVAL (subnormal) binary32 | 1.40·10−45 binary64 | 4.94·10−324 Наводит на мысль что мы приближаемся к нулю, но не достигаем его. Функция f(x) = 1/x
Для нуля есть представление "все нули" так что достигаем. Распределение чисел не гиперболическое, а скорее экспоненциальное, но не совсем из за артефактов представления.
1:34:30 а разве он это сделал ни для того, чтобы выравниться по кэш-линии? 4*16 - как раз 64. То есть за одну итерацию мы гарантированно ни разу не промахнёмся через кэш. А значит современный процессор сделает эти 4 сложения за 1 такт. Или я что-то совсем перемудрил?
@@sibedir за один такт он их не может сделать, там же зависимость от предыдущих вычислений в xmm0. В примере с fast-math оно хорошо ложится на конвейнер, потому что результаты независимы друг от друга, но конвейер не означает идеальную параллельность (можете почитать в википедии). Так же латенси floating point инструкций далеко не 1 такт (llvm-mca на моем процессоре показывает 8 тактов для movups и 3 такта для addps)
@@normanmaddyson8408а, ну да 🤦♂️ тупанул. Это же сумма в один регистр. И про 1 такт, тут не верно я сказал. Конечно же имелось в виду, что 4 разом выполнятся. Спасибо, что поправили.
Смотрится, как хороший фильм с закрученным сюжетом. Никогда не знаешь, что тебя ждёт за углом. Cliffhanger 10/10.
не перестаю восхищаться лектором и аудиторией. жаль что нет возможности на одинаковом уровне громкости слышать как лектора так и аудиторию. какждый ваш выпуск для меня настоящий праздник. доброго здоровья вам и вашим близким как лектору так и аудитории
Благодарю за лекцию ❤
Интересные лекции! Хоть и базовую часть знаешь, но юморок своё дело делает - фокус не теряется, так как не нуДно)
спасибо, попозже посмотрим обязательно)
ну и про union не забываем если нужно представить float как unsigned
Не используйте type punning.
По поводу кастинга - я понимаю почему кастинг не будет работать в случае кастинга в сторону не char. Т.к. он формирует выходные данные с учётом репрезентации типа. Но помимо char* существует ещё и void* который гарантирует что репрезентация будет исходной. Я бы прости приводил к void* и затем к dst.
Жалко два лайка нельзя поставить)
на тему извлечения битов: верно ли что union {float f; unsigned u;} это по сути тот же каст адреса и то же уб? И может ли в теории возникнуть ситуация, где каст/юнион и memcpy дадут разный результат?
Нет это т.н. type punning. У него более спорный статус. Его то запрещают то разрешают. Лучше им не пользоваться никогда. Но это не имеет отношения к strict aliasing.
Можно ли для получения битов float в int использовать reinterpret_cast вместо memcpy? Без указателей, просто интерпретировать значение. Если нет, то почему?
Нельзя т.к. это strict aliasing violation
@@tilir но… memcpy чем лучше? )
мы обманываем просто компилятор?
По итогу ведь и так и так получаем копию битового содержимого.
@@Денис-ь8ь7с наоборот. С помощью memcpy мы НЕ обманываем компилятор.
@@tilir Я подумаю над этим. Спасибо.
да, вместо abs(int) правильно реализовывать negabs(int)
И что эта функция должна делать?
@@tilirвозвращать отрицательную величину модуля аргумента, и далее работать только с отрицательными величинами, разве не так?
Интересная идея, спасибо. Я об этом почему-то раньше не думал и такой функции не встречал.
Для этого семинара в качестве задачи со звездочкой на дом подойдет разобрать работу алгоритму fast inverse square root из движка Quake 3
Мы будем эту задачу рассматривать но позднее. Для неё нужно понимать метод Ньютона. У нас будет отдельный семинар про научные вычисления.
3:00, Вами сказано "...трансцендентные числа, которые тоже вычислимы" .Это неверное утверждение.
В смысле неверное? Число пи трансцендентно и при этом вычислимо.
Константин, я не думал, что мне придётся это Вам пояснять. Но Ваше утверждение на лекции звучит, так - "Все трансцендентные числа - вычислимы", вот это утверждение неверно. Я не спорю с тем, что некоторые трансцендентные числа - вычислимы. Но я утверждаю, что почти все трансцендентные числа - не вычислимы.
@@КарлГаусс-ъ2и я не думал что меня именно так можно понять. Я разумеется имел в виду ту небольшую часть трансцендентных чисел которые тоже вычислимы.
А почему не используют1-байтовые float, разработчики железа, почему не делают такой функционал на cpu gpu? К примеру для расчета цвета пикселей c simd. Ведь по факту точность для 256 значений не важна в многих случаях.
А почему бы для пикселей не использовать однобайтовые целые?
Там где короткие floating point числа обоснованы -- в нейросетях например -- их делают. Всякие там bfloat16 и всё такое.
Но серьёзное обоснование именно для восьми бит с плавающей точкой (а сколько на мантиссу?) мне не встречалось.
@@tilir как раз в AI сейчас модно не только 8-bit float (2 вида, s1e4m3 и s1e5m2), но даже и 4-bit float (s1e2m1). Но за пределами AI они не очень-то применимы.
51:22 ну как можно было пропустить такую возможность оставить студентам 1.5f часа? 😆
Разве не около ±1-цы наибольшая плотность чисел т.к. экспонента минимальна.
А промежуток между -float_min и +float_min вообще выпадает, кроме нуля(ну это исключение).
Либо около min всё таки?
Вы не учитываете денормализованные числа.
@@tilir
Как раз про денормализованные числа речь.
format | MINVAL (subnormal)
binary32 | 1.40·10−45
binary64 | 4.94·10−324
Наводит на мысль что мы приближаемся к нулю, но не достигаем его. Функция f(x) = 1/x
Для нуля есть представление "все нули" так что достигаем. Распределение чисел не гиперболическое, а скорее экспоненциальное, но не совсем из за артефактов представления.
.1 0.5 .01 0.25 вещественные числа точно представляемые в эвм
Вы угадали ровно половину. 0.1 не может быть точно представлено в ieee754, у меня на видео есть пошаговое приближение. Найдите у себя вторую ошибку ))
я не отдупляю почему 0.1 не точное представление .5 @@tilir
Потому что 0.1 это (1 / 10), а 10 это не степень двойки.
1:34:30 а разве он это сделал ни для того, чтобы выравниться по кэш-линии? 4*16 - как раз 64. То есть за одну итерацию мы гарантированно ни разу не промахнёмся через кэш. А значит современный процессор сделает эти 4 сложения за 1 такт. Или я что-то совсем перемудрил?
Про кеши будет через пару занятий, мы их пока не проходили. А так да, это взаимосвязано.
@@tilir и про кэши будет ☺️ Как всё вкусно
@@sibedir за один такт он их не может сделать, там же зависимость от предыдущих вычислений в xmm0. В примере с fast-math оно хорошо ложится на конвейнер, потому что результаты независимы друг от друга, но конвейер не означает идеальную параллельность (можете почитать в википедии).
Так же латенси floating point инструкций далеко не 1 такт (llvm-mca на моем процессоре показывает 8 тактов для movups и 3 такта для addps)
@@normanmaddyson8408а, ну да 🤦♂️ тупанул. Это же сумма в один регистр.
И про 1 такт, тут не верно я сказал. Конечно же имелось в виду, что 4 разом выполнятся.
Спасибо, что поправили.
memcpy куда нибудь.