endbr64 🤔
Однажды я игрался в godbolt с виртуальными функциями по работе. Проставил необходимые флаги для сборки, читаю ассемблерный код и вижу инструкцию👨💻
Запустим godbolt с опцией
Он нам вернёт примерно следующее:
Теперь добавить опцию
Что происходит? Остановите землю!!!😮
Как известно, функция🤓 .
Но вот допустим, что у нас где-то появилось вредоносное ПО. Ну и по каким-то причинам ему нужно в😡 . Хорошо, ПО нашло в памяти кусок, подменило адрес функции main, вызывается другая функция и происходит... завершение программы. Почему?
Потому что у нас есть инструкция😇 . И когда мы вызывали другую функцию, там не было 🔼 .
Насколько я знаю, эта инструкция есть у семейства процессоров Intel в рамках технологии CET, которая позволяет избегать некоторые атаки на приложения. Но она не панацея: если бы у той функции была эта инструкция, могло бы произойти ужасное🥺 !
На самом деле процессоры сейчас настолько сложны, что в них очень много сделано для безопасности и это не бесплатно. В идеальном мире наши процессоры работали бы быстрее — просто потому что не нужно было дополнительную логику для обеспечения безопасности😐 .
Подробнее прочитать про то, как же всё-таки запускается приложения на
Интересное объяснение, зачем нужна инструкция
Однажды я игрался в godbolt с виртуальными функциями по работе. Проставил необходимые флаги для сборки, читаю ассемблерный код и вижу инструкцию
endbr64. "Это что за покемон такой?" — подумал я и начал копать. Запустим godbolt с опцией
-O2 на следующем примере: int main() {
return 0;
}
Он нам вернёт примерно следующее:
main:
xor eax, eax
retТеперь добавить опцию
-fcf-protection и получим уже следующее: main:
endbr64
xor eax, eax
retЧто происходит? Остановите землю!!!
Как известно, функция
main в C++ — это входная точка запуска приложения в операционной системе. Но до вызова этой функции происходит еще множество вещей под капотом, по типу чтения бинаря, инициализации ресурсов и т.д. Затем некоторая функция __libc_start_main всё же вызывает main Но вот допустим, что у нас где-то появилось вредоносное ПО. Ну и по каким-то причинам ему нужно в
runtime быстренько подменить функцию main (пока она еще не вызвалась из __libc_start_main), на другую, которая также находится в нашем бинарнике Потому что у нас есть инструкция
endbr64 endbr64 — процессор понял, что что-то не так, кинул клич и произошло экстренное завершение программы. Эта инструкция является некоторым сигналом о том, что вызов произошел успешно и можно двигаться дальше Насколько я знаю, эта инструкция есть у семейства процессоров Intel в рамках технологии CET, которая позволяет избегать некоторые атаки на приложения. Но она не панацея: если бы у той функции была эта инструкция, могло бы произойти ужасное
На самом деле процессоры сейчас настолько сложны, что в них очень много сделано для безопасности и это не бесплатно. В идеальном мире наши процессоры работали бы быстрее — просто потому что не нужно было дополнительную логику для обеспечения безопасности
Подробнее прочитать про то, как же всё-таки запускается приложения на
C++ можно здесь.Интересное объяснение, зачем нужна инструкция
endbr64 — здесь.Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🤯1🤡1💯1
Процессоры и их кэш 😐
В школе, когда мне рассказывали про кэш процессора я задавался вопросом: "А почему бы не сделать кэш процесса в кучу гигабайт?" Ну на самом деле, была бы жизнь слаще и веселее. Обычно ответ на этот вопрос: "Дорого". А что такое дорого?
Давай посмотрим на схему процессора, где расположены кэши процессора🤓 .
Дело в том, что:
1. Нам нужно проводить сигнал как можно скорее. Сам электрический ток. Через все логические элементы.
2. Нам нужно делать дополнительные проверки: чтобы быть безопаснее, чтобы поменьше было ошибок от случайных битов.
Таким образом, чтобы гарантировать время работы кэша, сигнал должен проходить супербыстро в случае
И собственно, в данном случае, "дорого" — это разработка. Придумать такую схему, чтобы🤔
В школе, когда мне рассказывали про кэш процессора я задавался вопросом: "А почему бы не сделать кэш процесса в кучу гигабайт?" Ну на самом деле, была бы жизнь слаще и веселее. Обычно ответ на этот вопрос: "Дорого". А что такое дорого?
Давай посмотрим на схему процессора, где расположены кэши процессора
L1 кэш максимально близко к ядрам. L2 — подальше, но при этом побольше. L3 — вообще далеко и супербольшой. И это не просто так. Дело в том, что:
1. Нам нужно проводить сигнал как можно скорее. Сам электрический ток. Через все логические элементы.
2. Нам нужно делать дополнительные проверки: чтобы быть безопаснее, чтобы поменьше было ошибок от случайных битов.
Таким образом, чтобы гарантировать время работы кэша, сигнал должен проходить супербыстро в случае
L1, чуть медленнее L2 и вообще медленно (в относительных единицах) — L3. Например, по информации здесь, доступ к кэшам работает за: L1 — 0.5 ns
L2 — 2.8 ns
L3 — 12.9 nsИ собственно, в данном случае, "дорого" — это разработка. Придумать такую схему, чтобы
L1 был на несколько гигабайт и доступ до него был бы примерно 0.5 ns по всей области покрытия — это было бы очень круто. Но пока, наверное, не получается. Но интересно, получится ли? Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4👍1🤔1🤡1🌭1
Восставший из мертвых
Мне иногда нравится поведение приложений, которые написаны на😂
Вспомним классику. В
После того, как мы закончили пользоваться этим объектам, правила хорошего тона гласят — уберись за собой:
На самом деле за операторами🤪 . Но не об этом сейчас.
Сделаем простой класс:
Этот класс хранит в себе переменную со стандартным значением
Теперь давайте создадим объект и вызовем у него
Никаких проблем. Теперь создадим ссылку на этот объект (ссылка по сути аналог ярлыка):
Удалим объект и вызовем
Тут давайте остановимся. Ссылка она ж ярлык. Мы когда файл удаляем — у нас ярлык становится невалидным. А тут почему-то работает. Что за магия😳 ?
А теперь создадим еще один объект и снова вызовем
Во-первых, почему😑 ?
На самом деле тут произошла вот какая магия:
1. Мы создали реальный объект в памяти;
2. Затем сказали программе — смотри, вот тебе ссылка на область памяти, там 100% лежит объект типа
3. Удалили объект, но программа всё еще думает, что по ссылке лежит реальный объект, и при этом знает, какую функцию вызвать — поэтому вызывает её, при этом она сама работает на невалидном участке памяти;
4. Потом снова создали объект — но времени так мало прошло, что программа просто в целях оптимизации положила объект в то же место, что и старый объект;
5. Теперь ссылка по сути указывает на область памяти, где реально лежит объект типа
Но на самом деле всё это —🤓 . Т.е. поведение, которое никак не определено стандартом и то, что у меня так получилось — мне повезло. 🥹 .
Под конец вопросик на сообразительность. Мы тут с вами обсуждали классы с виртуальными методами. Так вот если в класс добавить виртуальный метод — то программа вылетит с ошибкой. Почему?
UPD: А ошибочки не будет — всё же происходит UB. Подробности в комментариях.
Мне иногда нравится поведение приложений, которые написаны на
C++. И тут нравится скорее всего == “о, еще одно место, где можно прострелить ногу”.Вспомним классику. В
C++ мы можем создавать объекты через оператор new: A *a = new A(); // Здесь A — это какой-то класс, неважно какой
После того, как мы закончили пользоваться этим объектам, правила хорошего тона гласят — уберись за собой:
delete a; // Уничтожение объекта На самом деле за операторами
new и delete стоит множество магии: аллокация памяти, создание/удаление объекта Сделаем простой класс:
class A {
public:
void fun() {
++x;
std::cout << x << '\n'; // Просто выводим результат
};
private:
int x = 3;
};Этот класс хранит в себе переменную со стандартным значением
3. При вызове функции fun, значение в переменной увеличивается на единичку, а потом полученной значение выводится в командную строку. Теперь давайте создадим объект и вызовем у него
fun: A *a = new A();
a->fun(); // выведется 4Никаких проблем. Теперь создадим ссылку на этот объект (ссылка по сути аналог ярлыка):
A& b = *a; Удалим объект и вызовем
fun у b:delete a;
b.fun(); // может быть вывод каким угодно, но у меня 1Тут давайте остановимся. Ссылка она ж ярлык. Мы когда файл удаляем — у нас ярлык становится невалидным. А тут почему-то работает. Что за магия
А теперь создадим еще один объект и снова вызовем
fun у b: A *c = new A();
b.fun(); // может быть вывод каким угодно, но у меня 4Во-первых, почему
b всё еще работает? Во-вторых, как мы перескочили с 1 до 4 На самом деле тут произошла вот какая магия:
1. Мы создали реальный объект в памяти;
2. Затем сказали программе — смотри, вот тебе ссылка на область памяти, там 100% лежит объект типа
A;3. Удалили объект, но программа всё еще думает, что по ссылке лежит реальный объект, и при этом знает, какую функцию вызвать — поэтому вызывает её, при этом она сама работает на невалидном участке памяти;
4. Потом снова создали объект — но времени так мало прошло, что программа просто в целях оптимизации положила объект в то же место, что и старый объект;
5. Теперь ссылка по сути указывает на область памяти, где реально лежит объект типа
А, поэтому срабатывает валидный вызов функции.Но на самом деле всё это —
undefined behavior (UB) UB — очень тяжело отлавливаются и являются сложными багами в коде АUPD: А ошибочки не будет — всё же происходит UB. Подробности в комментариях.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥1🤡1
Small talks
У нас в Яндексе куча мероприятий, чтобы понимать что где как и зачем происходит☺️ . Естественно, что большая часть из них — это NDA. Мне они очень сильно нравятся, потому что я всегда хочу всё знать 🙂 Я надеюсь, что когда-нибудь и я выйду и расскажу всему Яндексу, что мы крутого сделали в команде! Но даже после них создается какое-то ощущение, что не хватает личных историй 😔 .
Я долго думал да гадал, как бы заполонить эту пропасть. Оказалось всё просто — пока ждешь, что приготовится твой кофе, можно поговорить с человеком, который следующий в очереди. И неважно, что вы возможно никогда не встретитесь в будущем (в Яндексе больше 18к человек), вы поделитесь из первых уст что у вас там интересненького🤔 .
Так вот на днях я познакомился с проджектом проекта из внутренней инфраструктуры Яндекса. И мало того, что мы обменялись текущими настроениями, я еще узнал о полезном инструменте, который ранее не знал, что вообще ВАУ😍 .
И так постоянно: кто-то делает проекты в web3 , кто-то оптимизировал в кучу раз продакшн и т.д. И вот тогда ты понимаешь: вокруг тебя мир всё-таки развивается😇 !
Друзья, small talks — наше всё!
У нас в Яндексе куча мероприятий, чтобы понимать что где как и зачем происходит
Я долго думал да гадал, как бы заполонить эту пропасть. Оказалось всё просто — пока ждешь, что приготовится твой кофе, можно поговорить с человеком, который следующий в очереди. И неважно, что вы возможно никогда не встретитесь в будущем (в Яндексе больше 18к человек), вы поделитесь из первых уст что у вас там интересненького
Так вот на днях я познакомился с проджектом проекта из внутренней инфраструктуры Яндекса. И мало того, что мы обменялись текущими настроениями, я еще узнал о полезном инструменте, который ранее не знал, что вообще ВАУ
И так постоянно: кто-то делает проекты в web3 , кто-то оптимизировал в кучу раз продакшн и т.д. И вот тогда ты понимаешь: вокруг тебя мир всё-таки развивается
Друзья, small talks — наше всё!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🤡1🐳1
Ох мои бенчмарки (Часть 1)😔
Сейчас на работе я занимаюсь оптимизацией нейронных сеток для мобилок🔼 . Оптимизация под них подразумевает под собой замеры:
— По метрикам качества;
— По скорости работы;
— По кушанию батарейки;
— По кушанию оперативки.
В большинстве случаев с первым пунктом проблем нет: написал скрипты для прогона, посчитал по результатам метрики, сделал выводы. С третьим и четвертым достаточно инструментов от вендоров: на android это профилировщик Android Studio, на iOS — профилировщик Xcode. А вот со вторым проблема. Много проблем.😮
🤔 Первое: под девайс надо собрать бенчмарк. Это, казалось бы простое дельце, только кажется таким. Приходится убивать много времени для того, чтобы совместить все версии библиотек на всех девайсах.
🤔 Второе: некоторые версии бенчмарка не поддерживают какие-то операции с сетью, а некоторые работают отлично. Тут варианта два: думать как-то над архитектурой сети или над версией бенчмарка. Архитектуру менять очень не хочется (это повлечет много работы по обучению сети), тем более она работает на более свежих версиях. Приходится менять версию. Но это влечет за собой то, что придется менять версию всей библиотеки в продакшн-коде. А учитывая, что у нас монорепа, это сделать ой как не просто: то, что у меня чего-то там не запускается, так себе причина менять в монорепе — у всех же работает.
🤔 Третье: троттлинг (механизм защиты процессора от перегрева путем занижения производительности). Если запустить наши нейронки на среднестатистическом ПК на CPU — я уверяю вас, они будут летать и вы даже этого не заметите. Но на телефонах всё не так просто. Там другие процессоры и компоненты, они больше подвержены перегреву. А для бенчмарков важно иметь +- стабильную производительность. Я уже не говорю о том, что чиселки должны из раза в раз повторяться по одному и тому же тесту.
🤔 Четвертое: тестов ОЧЕНЬ много. Больше 500 на один девайс. Нужно думать о том, как их провести и как потом интерпретировать. 500 чиселок очень сложно просматривать (поверьте мне). Более того, сами по себе тесты разные и некоторые между собой (внутри одного девайса) не сравнимы. Например, есть замеры на CPU, GPU, NPU и т.д.
🤔 Пятое: девайсы могут оключаться и включаться, перезагружаться, обновляться и прочие радости жизни. Нужно уметь несмотря на всё это восстанавливать проведение замеров, а именно продолжать с того места, откуда всё закончилось. И при этом сохранить себе нервы.
Первая проблема решается вручную. По второй проблеме я надеюсь доказать, что замена всё же необходима.👨💻 А по всем остальным проблемам решение я расскажу в следующем посте.☺️
Сейчас на работе я занимаюсь оптимизацией нейронных сеток для мобилок
— По метрикам качества;
— По скорости работы;
— По кушанию батарейки;
— По кушанию оперативки.
В большинстве случаев с первым пунктом проблем нет: написал скрипты для прогона, посчитал по результатам метрики, сделал выводы. С третьим и четвертым достаточно инструментов от вендоров: на android это профилировщик Android Studio, на iOS — профилировщик Xcode. А вот со вторым проблема. Много проблем.
🤔 Первое: под девайс надо собрать бенчмарк. Это, казалось бы простое дельце, только кажется таким. Приходится убивать много времени для того, чтобы совместить все версии библиотек на всех девайсах.
🤔 Второе: некоторые версии бенчмарка не поддерживают какие-то операции с сетью, а некоторые работают отлично. Тут варианта два: думать как-то над архитектурой сети или над версией бенчмарка. Архитектуру менять очень не хочется (это повлечет много работы по обучению сети), тем более она работает на более свежих версиях. Приходится менять версию. Но это влечет за собой то, что придется менять версию всей библиотеки в продакшн-коде. А учитывая, что у нас монорепа, это сделать ой как не просто: то, что у меня чего-то там не запускается, так себе причина менять в монорепе — у всех же работает.
🤔 Третье: троттлинг (механизм защиты процессора от перегрева путем занижения производительности). Если запустить наши нейронки на среднестатистическом ПК на CPU — я уверяю вас, они будут летать и вы даже этого не заметите. Но на телефонах всё не так просто. Там другие процессоры и компоненты, они больше подвержены перегреву. А для бенчмарков важно иметь +- стабильную производительность. Я уже не говорю о том, что чиселки должны из раза в раз повторяться по одному и тому же тесту.
🤔 Четвертое: тестов ОЧЕНЬ много. Больше 500 на один девайс. Нужно думать о том, как их провести и как потом интерпретировать. 500 чиселок очень сложно просматривать (поверьте мне). Более того, сами по себе тесты разные и некоторые между собой (внутри одного девайса) не сравнимы. Например, есть замеры на CPU, GPU, NPU и т.д.
🤔 Пятое: девайсы могут оключаться и включаться, перезагружаться, обновляться и прочие радости жизни. Нужно уметь несмотря на всё это восстанавливать проведение замеров, а именно продолжать с того места, откуда всё закончилось. И при этом сохранить себе нервы.
Первая проблема решается вручную. По второй проблеме я надеюсь доказать, что замена всё же необходима.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7😱1🤡1
Ох мои бенчмарки (Часть 2)😔
Как вы могли догадаться из предыдущего поста — вручную запускать я это собираюсь😂 . У меня несколько девайсов, на каждом более 600 тестов (да-да, за выходные еще добавилось). И кажется не для того меня нанимали, чтобы я такими вещами занимался. Конечно, нужно как-то автоматизировать 💃 .
Замечу сразу — я писал обёртку для запуска готового инструмента из либы. И это по нескольким причинам:
🤔Только авторы либы обладают полным пониманием, как она работает, и способны написать тесты, которые учитывают много нюансов работы;
🤔 Даже если бы я собрался писать — это месяц, а то и больше времени работы, что естественно бессмысленно при наличии готового инструмента;
🤔 Многопоточные CPU приложения замерять сложно, GPU приложения замерять многократно сложнее;
🤔 Готовые инструменты как правило представляют подробную статистику что и как исполнялось, а не только общее число выдаёт — это очень полезно;
🤔 Если у либы нет такого инструмента, то возникает большой вопрос об эффективности этой библиотеки.
Утилита, которую я использую имеет множество параметров и определенное подмножество — это один эксперимент. Естественно, мне не нужны все подмножества данного множества: только определенные эксперименты были выбраны вручную 💪. Каждый эксперимент должен исполняться для каждой модели и для каждого окружения.
В целом подстановку всех этих параметров можно сделать путем написания нескольких вложенных циклов (хотя на деле лучше использовать hydra, что я и сделал), но есть проблема — если упадет, то придется начинать всё сначала😮 . На помощь приходить генерация плана тестов.
В моём случае план тестов — это определенная структура папок, где для каждого девайса есть папки каждого окружения, в которых для каждой модели тоже есть папки и т.д. В самых глубоких папках лежат результаты запуска каждого теста. Теперь проверка того, выполнялся ли тест становится проще — мы просто проверяем, лежат ли файлы с результатами по заданному адресу теста для девайса🔼 . Поэтому если что-то упадет, всегда можно просто перезапустить команду, она продолжит выполнять только те тесты, которые еще не были исполнены.
Маленькая ремарка: отслеживание прерывания тестов можно было бы как-то автоматически отслеживать, но в этом нет смысла: если что-то упало, то надо смотреть вручную, мб там телефон сгорел или перегрелся🤪 .
Проблема с тротлингом решается запуском тестов через какой-то промежуток времени. Мои эксперименты показали, что этого достаточно, чтобы не нагружать девайс от слова совсем😇 .
После всего многообразия тестов нужно как-то представить результаты. Я быстренько накидал скрипт на Python, который строит графики по необходимым срезам, а также генерирует таблички по окружениям в markdown стиле. Графики помогают оценить тренд в общем, а таблички уже для более детального анализа спорных моментов.
На деле оказалось куда проще, чем казалось😃
Как вы могли догадаться из предыдущего поста — вручную запускать я это собираюсь
Замечу сразу — я писал обёртку для запуска готового инструмента из либы. И это по нескольким причинам:
🤔Только авторы либы обладают полным пониманием, как она работает, и способны написать тесты, которые учитывают много нюансов работы;
🤔 Даже если бы я собрался писать — это месяц, а то и больше времени работы, что естественно бессмысленно при наличии готового инструмента;
🤔 Многопоточные CPU приложения замерять сложно, GPU приложения замерять многократно сложнее;
🤔 Готовые инструменты как правило представляют подробную статистику что и как исполнялось, а не только общее число выдаёт — это очень полезно;
🤔 Если у либы нет такого инструмента, то возникает большой вопрос об эффективности этой библиотеки.
Утилита, которую я использую имеет множество параметров и определенное подмножество — это один эксперимент. Естественно, мне не нужны все подмножества данного множества: только определенные эксперименты были выбраны вручную 💪. Каждый эксперимент должен исполняться для каждой модели и для каждого окружения.
В целом подстановку всех этих параметров можно сделать путем написания нескольких вложенных циклов (хотя на деле лучше использовать hydra, что я и сделал), но есть проблема — если упадет, то придется начинать всё сначала
В моём случае план тестов — это определенная структура папок, где для каждого девайса есть папки каждого окружения, в которых для каждой модели тоже есть папки и т.д. В самых глубоких папках лежат результаты запуска каждого теста. Теперь проверка того, выполнялся ли тест становится проще — мы просто проверяем, лежат ли файлы с результатами по заданному адресу теста для девайса
Маленькая ремарка: отслеживание прерывания тестов можно было бы как-то автоматически отслеживать, но в этом нет смысла: если что-то упало, то надо смотреть вручную, мб там телефон сгорел или перегрелся
Проблема с тротлингом решается запуском тестов через какой-то промежуток времени. Мои эксперименты показали, что этого достаточно, чтобы не нагружать девайс от слова совсем
После всего многообразия тестов нужно как-то представить результаты. Я быстренько накидал скрипт на Python, который строит графики по необходимым срезам, а также генерирует таблички по окружениям в markdown стиле. Графики помогают оценить тренд в общем, а таблички уже для более детального анализа спорных моментов.
На деле оказалось куда проще, чем казалось
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2🤡1
Чему я научился за 5 лет профессиональной разработки?
Я делаю приложения / строю сервисы / разрабатываю уже более пяти лет. За это время я успел: написать свой собственный игровой движок, кучу алгоритмов быстрого всего, качественно обучить десятки нейросетей, поработать над разработкой робототехнической платформы и многое многое другое. Между этим еще удалось поруководить двумя командами разработки в общей сумме в которых было около 10 человек. Поэтому, я думаю, мне есть что сказать, хотя не претендую на экспертность.
💻 Кодить — это только кодить. А разрабатывать — это не только лишь кодить.
Когда ты приходишь молодой и свежий, а твоё подсознательное желание запилить 100500 багов велико, обычно мысли о том, как круто кодить. Со временем старшие коллеги тебе поясняют (да и сам доходишь), что в профессии разработчика нужно не только кодить, но и понимать бизнес, создавать и уточнять требования, строить архитектуру, и многие другие вещи, которые в начале пути могут показаться даже скучными.
💻 Количество и качество твоих вопросов определяет твой профессионализм.
Кто бы что не говорил, но любой профессионал задаёт с большей вероятностью вопросы, без которых реализация компонентов невозможна. И, как мне кажется, это в любой области так. Природа этих вопросов — исключительно опыт. Собственно, обычно на собеседованиях я по вопросам кандидата уже могу составить общую картинку об опыте человека. Когда я работаю с новенькими ребятами, стараюсь заставлять их думать и задавать правильные вопросы.
💻 Любой код написан не просто так. Прежде чем его исправлять, подумай, почему сделали именно так?
Я очень люблю и ценю этот урок. На заре моего становления мне попался какой-то фреймворк, в котором было всё не так (как я думал). Я прихожу к руководителю и говорю примерно: "да тут изи сделать, а они не могут, давайте просто напишем своё?" На что был жесткий ответ: "Антоха, вот смотри у этого фреймворка 100+ контрибов, 3к+ звезд на гитхабе. Думаешь, они настолько тупые, что не могли пофиксить такие очевидные вещи? Ты думал о требованиях, которые они ставили? Понимаешь, какие задачи они решают?" И именно тогда пришло ко мне осознание, что.. всё не просто так.
💻 Изучай инструменты.
Всё что ты используешь — должно быть изучено тобой как можно глубже (но без фанатизма). Сверлить плитку дрелью конечно просто, но от выбора сверла зависит — треснет она или нет.
💻 Документация и тесты важны.
Кто бы мне что не говорил, но если у вас нет одного или другого — значит у вас проблемы в проекте. Он будет не понятен новеньким, у вас будут постоянные баги, вы будете уйму времени тратить на то, чтобы пофиксить что-то, потому что нужно перелопатить половину проекта. Но и без фанатизма, конечно.
💻 Команда и атмосфера внутри неё мега важны.
Вы можете быть самым классным спецом во всей вселенной, но в одиночку вы сделаете меньше, чем в классной команде. И команда классная не только тогда, когда вы укладываетесь в спринт или цели, а когда внутри есть некоторый вайб, поддержка, взаимовыручка. Я считаю, отличная команда хороша не только на работе, но и в неформальной обстановке. В такой среде ты реально кайфуешь и делаешь свою работу не только эффективно, но и с любовью. Из прошлой команды я уходил чуть ли не со слезами на глазах, потому что всегда больно расставаться с великолепным коллективом.
Я делаю приложения / строю сервисы / разрабатываю уже более пяти лет. За это время я успел: написать свой собственный игровой движок, кучу алгоритмов быстрого всего, качественно обучить десятки нейросетей, поработать над разработкой робототехнической платформы и многое многое другое. Между этим еще удалось поруководить двумя командами разработки в общей сумме в которых было около 10 человек. Поэтому, я думаю, мне есть что сказать, хотя не претендую на экспертность.
💻 Кодить — это только кодить. А разрабатывать — это не только лишь кодить.
Когда ты приходишь молодой и свежий, а твоё подсознательное желание запилить 100500 багов велико, обычно мысли о том, как круто кодить. Со временем старшие коллеги тебе поясняют (да и сам доходишь), что в профессии разработчика нужно не только кодить, но и понимать бизнес, создавать и уточнять требования, строить архитектуру, и многие другие вещи, которые в начале пути могут показаться даже скучными.
💻 Количество и качество твоих вопросов определяет твой профессионализм.
Кто бы что не говорил, но любой профессионал задаёт с большей вероятностью вопросы, без которых реализация компонентов невозможна. И, как мне кажется, это в любой области так. Природа этих вопросов — исключительно опыт. Собственно, обычно на собеседованиях я по вопросам кандидата уже могу составить общую картинку об опыте человека. Когда я работаю с новенькими ребятами, стараюсь заставлять их думать и задавать правильные вопросы.
💻 Любой код написан не просто так. Прежде чем его исправлять, подумай, почему сделали именно так?
Я очень люблю и ценю этот урок. На заре моего становления мне попался какой-то фреймворк, в котором было всё не так (как я думал). Я прихожу к руководителю и говорю примерно: "да тут изи сделать, а они не могут, давайте просто напишем своё?" На что был жесткий ответ: "Антоха, вот смотри у этого фреймворка 100+ контрибов, 3к+ звезд на гитхабе. Думаешь, они настолько тупые, что не могли пофиксить такие очевидные вещи? Ты думал о требованиях, которые они ставили? Понимаешь, какие задачи они решают?" И именно тогда пришло ко мне осознание, что.. всё не просто так.
💻 Изучай инструменты.
Всё что ты используешь — должно быть изучено тобой как можно глубже (но без фанатизма). Сверлить плитку дрелью конечно просто, но от выбора сверла зависит — треснет она или нет.
💻 Документация и тесты важны.
Кто бы мне что не говорил, но если у вас нет одного или другого — значит у вас проблемы в проекте. Он будет не понятен новеньким, у вас будут постоянные баги, вы будете уйму времени тратить на то, чтобы пофиксить что-то, потому что нужно перелопатить половину проекта. Но и без фанатизма, конечно.
💻 Команда и атмосфера внутри неё мега важны.
Вы можете быть самым классным спецом во всей вселенной, но в одиночку вы сделаете меньше, чем в классной команде. И команда классная не только тогда, когда вы укладываетесь в спринт или цели, а когда внутри есть некоторый вайб, поддержка, взаимовыручка. Я считаю, отличная команда хороша не только на работе, но и в неформальной обстановке. В такой среде ты реально кайфуешь и делаешь свою работу не только эффективно, но и с любовью. Из прошлой команды я уходил чуть ли не со слезами на глазах, потому что всегда больно расставаться с великолепным коллективом.
🔥7👍5🤔2💩1🤡1🏆1
Оптимизация работы диска
Linux — это очень сложная штука. Я уверен, что среднестатестический пользователь тратит просто уйму потенциала железа впустую, просто потому что он даже понятия не имеет, как настраивать систему оптимально под его железо. Но это и не нужно, только если вы не занимаетесь этим профессионально👨💻 .
Одни из таких настроек — это параметры файловой системы. Любое ваше взаимодействие фиксируется: изменение файла, доступ к нему и т.д. Просто представьте себе: вы просто захотели открыть файл, а где-то внутри обновилось время обращения к файлу. Это необходимо, чтобы находить ошибки в файловой системе вовремя и исправлять их, а также для восстановления.
Но что если мы сохранили наши данные где-то на жестких дисках в датацентрах, а сейчас нам нужна максимальная производительность🤔 ? Мы можем пожертвовать ошибками и восстановлением, потому что данные просто можно будет еще раз скопировать (это просто дёшево). Например, если в 😔 .
Здесь пишут, что это в современных версиях уже не даёт существенного ускорения. Но если вы работаете с HDD, то точно должно докидывать (пару лет назад так было у меня, когда я читал сотни тысяч картинок для обучения).
И таких параметров много, подробнее здесь. Я не знаю большинство из них, но если когда-то придется оптимизировать работу файловой системы, я знаю что делать. И вы тоже🙃
Linux — это очень сложная штука. Я уверен, что среднестатестический пользователь тратит просто уйму потенциала железа впустую, просто потому что он даже понятия не имеет, как настраивать систему оптимально под его железо. Но это и не нужно, только если вы не занимаетесь этим профессионально
Одни из таких настроек — это параметры файловой системы. Любое ваше взаимодействие фиксируется: изменение файла, доступ к нему и т.д. Просто представьте себе: вы просто захотели открыть файл, а где-то внутри обновилось время обращения к файлу. Это необходимо, чтобы находить ошибки в файловой системе вовремя и исправлять их, а также для восстановления.
Но что если мы сохранили наши данные где-то на жестких дисках в датацентрах, а сейчас нам нужна максимальная производительность
/etc/fstab добавить noatime к параметрам монтирования диска, то как раз OS перестанет журналировать время последнего обращения к файлу. Это снизит немного нагрузку на диск, потому что раньше обращения к файлу нужно было синхронизировать и журналировать Здесь пишут, что это в современных версиях уже не даёт существенного ускорения. Но если вы работаете с HDD, то точно должно докидывать (пару лет назад так было у меня, когда я читал сотни тысяч картинок для обучения).
И таких параметров много, подробнее здесь. Я не знаю большинство из них, но если когда-то придется оптимизировать работу файловой системы, я знаю что делать. И вы тоже
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍3🤡1🏆1
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
⚡2🔥2😁1🤡1
Почему нейронные сети могут долго исполняться на мобильных устройствах?
На днях прочитал статью "An Improved One millisecond Mobile Backbone" от ребят из Apple об их взгляде на быстрые сетки для мобильных устройств. В ней рассматривается архитектура нейронной сети, которая по заверениям, работает очень быстро и относительно очень точно. Сама сеть является основой для множества задач компьютерного зрения: классификации, сегментации, поиск объектов и т.д.
Авторы выделяют две основные проблемы в нейронных сетях из-за которых последние работаю очень долго:
🤔 Используются дорогие функции активации
Любое действие стоит процессорного времени и вычисление сигмоиды стоит дороже взятия максимума, как это делается в ReLU😃 .
🤔 Слишком много ветвлений
В настоящий момент в нейронных сетях часто используется операция свертка, которую здорово научились исполнять параллельно (особенно для специфичных сверточных слоёв). Но чтобы features быстро не беднели😁 , обычно ставят skip-connections, которые идут параллельно основному потоку информации. Это приводит к тому, что во время исполнения нейронной сети необходимо ставить сихнронизации на точки соединения. Синхронизация — дорого 😔 , поэтому и долго.
Если с первой проблемой побороться можно: придумать хитрую быструю функцию активации или как-то модифицировать ReLU, то со второй проблемой не понятно чего делать. Дело в том, что skip-connections нам нужны, чтобы нейронные сети делать действительно глубокими, а features богатыми и представляющими что-то из себя🥺 .
Авторы решают последнюю проблему следующим образом: во время обучения они используют skip-connections, а для инференса делают репараметризацию нейронной сети таким образом, чтобы этих skip-connections не было (подробнее лучше узнать в статье). Таким образом, у них получается линейная структура сети, которая практически не имеет точек синхронизации🔼 .
В статье есть таблички, где показывается скорость и точность полученной сети и сравнение с аналогами. При одинаковом числе параметров, сеть действительно работает быстрее (по крайней мере в статье) и точнее🔼 .
Что мне не понравилось в статье:
🤔 Использовали только iPhone 12 для экспериментов на мобилках
Думаю, можно было взять и побольше линейку iPhone.
🤔 Замеряли скорость на CPU на серверном процессоре – Intel Xeon Gold 5118
Это действительно было необходимо в статья про мобильные нейронные сети?
🤔 Есть замеры только на нейронных графических ускорителях
Это, конечно, хорошо, но я мб хочу запускать сеть на CPU, а результатов нет.
🤔 Есть замеры времени для классификации, но не для остальных задач
Или у них что-то пошло не так, или я что-то не понимаю. Неужели так сложно было замерить?
В целом, как по мне, статья годная. Как руки дотянутся, попробую их сеть у себя☺️ .
На днях прочитал статью "An Improved One millisecond Mobile Backbone" от ребят из Apple об их взгляде на быстрые сетки для мобильных устройств. В ней рассматривается архитектура нейронной сети, которая по заверениям, работает очень быстро и относительно очень точно. Сама сеть является основой для множества задач компьютерного зрения: классификации, сегментации, поиск объектов и т.д.
Авторы выделяют две основные проблемы в нейронных сетях из-за которых последние работаю очень долго:
Любое действие стоит процессорного времени и вычисление сигмоиды стоит дороже взятия максимума, как это делается в ReLU
В настоящий момент в нейронных сетях часто используется операция свертка, которую здорово научились исполнять параллельно (особенно для специфичных сверточных слоёв). Но чтобы features быстро не беднели
Если с первой проблемой побороться можно: придумать хитрую быструю функцию активации или как-то модифицировать ReLU, то со второй проблемой не понятно чего делать. Дело в том, что skip-connections нам нужны, чтобы нейронные сети делать действительно глубокими, а features богатыми и представляющими что-то из себя
Авторы решают последнюю проблему следующим образом: во время обучения они используют skip-connections, а для инференса делают репараметризацию нейронной сети таким образом, чтобы этих skip-connections не было (подробнее лучше узнать в статье). Таким образом, у них получается линейная структура сети, которая практически не имеет точек синхронизации
В статье есть таблички, где показывается скорость и точность полученной сети и сравнение с аналогами. При одинаковом числе параметров, сеть действительно работает быстрее (по крайней мере в статье) и точнее
Что мне не понравилось в статье:
Думаю, можно было взять и побольше линейку iPhone.
Это действительно было необходимо в статья про мобильные нейронные сети?
Это, конечно, хорошо, но я мб хочу запускать сеть на CPU, а результатов нет.
Или у них что-то пошло не так, или я что-то не понимаю. Неужели так сложно было замерить?
В целом, как по мне, статья годная. Как руки дотянутся, попробую их сеть у себя
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥2😱1🤡1
Долой рабочие встречи, всё время на разработку!
Именно с таким лозунгом мне приходилось иногда сталкиваться, пока я был тимлидом😔 . Да что уж там, я сам таким был, пока… не стал тимлидом. Что же поменялось?
Даже в небольшом проекте порой сложно разобраться будучи разработчиком, что уж говорить, если ты тимлид. Ты меньше работаешь над кодом, можешь не знать всех тонкостей, но тебе нужно продолжать разбираться в проекте. А еще следить, какой там прогресс по фичам.. А еще за мотивацией сотрудников. А еще за сроками... А еще.. ой, что-то я увлекся🤣
В общем, большинство командных митингов нужны только тимлиду, и для того, чтобы понимать статус проекта, понимать идеи, которые реализуются и быть на чеку что и как.
По началу я этого не понимал. Поэтому плодил митингов, сам не думая, для чего это нужно. Но когда мне стали жаловаться разрабы о том, что мы только болтаем, а не проекты делаем — я задумался😳 . И не подумайте, что я не читал никакой литературы про управление проектами, просто одно дело теория, другое — практика.
После этого инцидента я очень тщательно думаю над постановкой и целью митингов, а если мне кто-то их ставит — всегда интересуюсь назначением. Теперь я не отношусь к митингам как к мероприятию, которое бесполезно тратит моё драгоценное время.
Какой вывод: если вам не понятно, зачем ставится встреча — поинтересуйтесь у вашего руководителя. Может быть он и сам не знает, а может быть поможет вам понять☺️
Именно с таким лозунгом мне приходилось иногда сталкиваться, пока я был тимлидом
Даже в небольшом проекте порой сложно разобраться будучи разработчиком, что уж говорить, если ты тимлид. Ты меньше работаешь над кодом, можешь не знать всех тонкостей, но тебе нужно продолжать разбираться в проекте. А еще следить, какой там прогресс по фичам.. А еще за мотивацией сотрудников. А еще за сроками... А еще.. ой, что-то я увлекся
В общем, большинство командных митингов нужны только тимлиду, и для того, чтобы понимать статус проекта, понимать идеи, которые реализуются и быть на чеку что и как.
По началу я этого не понимал. Поэтому плодил митингов, сам не думая, для чего это нужно. Но когда мне стали жаловаться разрабы о том, что мы только болтаем, а не проекты делаем — я задумался
После этого инцидента я очень тщательно думаю над постановкой и целью митингов, а если мне кто-то их ставит — всегда интересуюсь назначением. Теперь я не отношусь к митингам как к мероприятию, которое бесполезно тратит моё драгоценное время.
Какой вывод: если вам не понятно, зачем ставится встреча — поинтересуйтесь у вашего руководителя. Может быть он и сам не знает, а может быть поможет вам понять
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6💩2❤1🤡1
Дела насущные
В последнее время никак не могу найти времени, чтобы подготовить для вас классный материал о том, как работают страницы памяти в Linux🤓 . Обычно я сначала прогоняю материал через себя, а потом даю краткое резюме в этом блоге с ссылочками. Это позволяет мне как-то развиваться, а вам узнавать что-то новое и интересное.☺️
Всё рабочее, да и свободное время, у меня занимают сон и работа в последнее время. Хочется уйти на праздники с чистой головой и отдохнуть без мыслей о работе😉 .
За последнии пару недель я дебажил и фиксил очень много кода, закончил эксперименты с бенчмарками моих моделей и приступил к следующей фазе реализации фичи. Пока команде всё нравится и самое главное, что мне тоже нравится😍 . Я верю, что внедрение этой фичи даст огромный прирост к качеству нашего решения. До конца года планирую сделать расписание экспериментов и автоматизировать это, чтобы за выходныё всё просчиталось👨💻 .
Параллельно я читаю много документации и кода из TensorFlow и внутренних инструментов. Осваиваю много инфраструктурных мелочей, которые в совокупе при грамотном использовании помогут сделать мне конфекту. При этом стараюсь разобраться, почему сделано именно так, а не по другому — это очень важно в больших системах🤓 .
Недавно также нас поблагодарила другая команда из компании: мы очень им помогаем и они не верят своим, что так можно☺️ ! Как будут офиициальные анонсы, я обязательно про это расскажу, а пока просто хотел поделиться какой-то радостью.
Из грустного: стало как-то печальненько на удаленочке, хочется затусить со своей командой вживую. Думаю, в следующем году как-нибудь это устроим!😇
В последнее время никак не могу найти времени, чтобы подготовить для вас классный материал о том, как работают страницы памяти в Linux
Всё рабочее, да и свободное время, у меня занимают сон и работа в последнее время. Хочется уйти на праздники с чистой головой и отдохнуть без мыслей о работе
За последнии пару недель я дебажил и фиксил очень много кода, закончил эксперименты с бенчмарками моих моделей и приступил к следующей фазе реализации фичи. Пока команде всё нравится и самое главное, что мне тоже нравится
Параллельно я читаю много документации и кода из TensorFlow и внутренних инструментов. Осваиваю много инфраструктурных мелочей, которые в совокупе при грамотном использовании помогут сделать мне конфекту. При этом стараюсь разобраться, почему сделано именно так, а не по другому — это очень важно в больших системах
Недавно также нас поблагодарила другая команда из компании: мы очень им помогаем и они не верят своим, что так можно
Из грустного: стало как-то печальненько на удаленочке, хочется затусить со своей командой вживую. Думаю, в следующем году как-нибудь это устроим!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥3🤡1
Итоги 2022
За этот год я выполнил 22 цели из 34 поставленных в прошлом году☺️ . 31 декабря, пока салаты будут делаться, кола питься, чипсы кушаться и прочие радости жизни происходить, я буду планировать цели на 2023.
А вот главные достижения этого года:
🔼 Я закончил свой длительный цикл образования и получил степень магистра с отличием;
🔼 Написал полностью свою научную статью и выступил на конференции — понял, что наука вообще не моё;
🔼 Перешёл на работу в Яндекс — больше отвественности, более серьезные задачи и требования;
🔼 Занялся личными финансами и инвестициями — недавано закончил составлять инвестиционную стратегию на ближайшие 10 лет;
🔼 Проработал множество моментов с личным психологом и стал просто лучше себя понимать.
И еще пару инетерсных вещей, которые точно заслуживают вашего прочтения, о которых вы узнаете совсем скоро😉 .
В будущем году я постраюсь копать глубже в интересные мне направления и технологии — это и оптимизация софта верхнеуровневая, низкоуровневая; проектирование масштабируемых высоконагруженных сервисов. Но в любом случае, не забывать про развитие вширь: изучать вокруг всё и вся🙃 !
В будущем году я постраюсь лучше отдыхать (а не работать 24/7), настроить свой сон и отладить систему time-management (у меня что-то типа GTD).
В будущем году постараюсь больше быть с людьми. Люди — самый ценный актив🥰 !
UPD: на выходных можете почитать про базовые концепции аллокаторов. Я буду вместе с вами!
За этот год я выполнил 22 цели из 34 поставленных в прошлом году
А вот главные достижения этого года:
И еще пару инетерсных вещей, которые точно заслуживают вашего прочтения, о которых вы узнаете совсем скоро
В будущем году я постраюсь копать глубже в интересные мне направления и технологии — это и оптимизация софта верхнеуровневая, низкоуровневая; проектирование масштабируемых высоконагруженных сервисов. Но в любом случае, не забывать про развитие вширь: изучать вокруг всё и вся
В будущем году я постраюсь лучше отдыхать (а не работать 24/7), настроить свой сон и отладить систему time-management (у меня что-то типа GTD).
В будущем году постараюсь больше быть с людьми. Люди — самый ценный актив
UPD: на выходных можете почитать про базовые концепции аллокаторов. Я буду вместе с вами!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥17🤡1💯1
Аллокаторы?
Итак, я всё же прочитал статью про аллокаторы. А вы🙃 ? Я не то, чтобы специалист по ним, но всё же давайте поясню, зачем нам нужен этот зверь. Если кратко: для управления памятью 👨🦳 . А теперь подробнее.
Представьте покупку билетов в кино на семейную комедию. Обычно на такие произведения искусства ходят парами, компаниями людей. По крайней мере, лично я никогда не ходил один😁 . Когда вы покупаете билеты на всю группу людей, у вас возникает задача: как бы сесть всем рядом. Кто-то занимает два места, кто-то занимает 4 места в двух рядах и т.д. Некоторые люди еще не любят, чтобы рядом с ними кто-то сидел — поэтому они отставляют от занятых мест одно сиденье. Возникает фрагментация, т.е. такая ситуация, когда вроде места еще есть, но уже не сесть компанией — потому что остались единичные места по всему залу. И вроде как кинотеатр теряет деньги, но с другой стороны все те клиенты, кто купил билеты, по идее счастливы (ну наверное) 🤣 .
Теперь представьте ресторан. Когда вы приходите, обычно встречающий вас персонал старается выделить столик именно под вас: если вас двое — столик на двоих; трое или четверо — столик на четверых; а для целой компании обычно заготовлен огромный стол или отдельный банкетный зал — такую роскошь редко дадут паре человек, как бы они того не хотели. А еще иногда столики соединяют — всё ради гостей заведения. И казалась бы тут тоже есть фрагментация, но есть один нюанс🙃 .
В обоих случаях есть своя система распределения (аллокации) ресурсов. Только вот в случае кино вы делаете всё сами: и выбираете места, и боритесь за них🫡 , и оставляете пустое пространство рядом. В случае ресторана всё делают за вас 🔼 : вам лишь необходимо сказать сколько вас пришло. А ресторан уже сам там решит, куда вас поместить, что нужно сделать и самое главное — с максимальной выгодой для себя.
В программировании всё то же самое. Распределением памяти занимается аллокатор. Самый стандартный для
Но у нас мир сложный. Разные бизнес-требования, разные доменные области😳 . А везде хочется получаться максимально эффективное приложение. Поэтому есть множество разных аллокаторов, которые решают разные задачи. Где-то нужно сразу выделить огромный кусок памяти, а где-то нужна заточка на работу с мелкими кусками. Где-то делается упор на уменьшение системных вызовов (которые очень дорогие), а где-то на сокращение фрагментации.
То, какой аллокатор выбрать — зависит от вашего приложения. Но перед этим продумайте систему performance тестов, которая покрывает значительную часть пользовательского железа и пользовательских сценариев, потому что не всегда теория совпадает с практикой🤓 .
Итак, я всё же прочитал статью про аллокаторы. А вы
Представьте покупку билетов в кино на семейную комедию. Обычно на такие произведения искусства ходят парами, компаниями людей. По крайней мере, лично я никогда не ходил один
Теперь представьте ресторан. Когда вы приходите, обычно встречающий вас персонал старается выделить столик именно под вас: если вас двое — столик на двоих; трое или четверо — столик на четверых; а для целой компании обычно заготовлен огромный стол или отдельный банкетный зал — такую роскошь редко дадут паре человек, как бы они того не хотели. А еще иногда столики соединяют — всё ради гостей заведения. И казалась бы тут тоже есть фрагментация, но есть один нюанс
В обоих случаях есть своя система распределения (аллокации) ресурсов. Только вот в случае кино вы делаете всё сами: и выбираете места, и боритесь за них
В программировании всё то же самое. Распределением памяти занимается аллокатор. Самый стандартный для
C++ аллокатор практически ручной — он создан специально таким образом, чтобы выполнить свою главную задачу: просто выделить память пользователю. Но у нас мир сложный. Разные бизнес-требования, разные доменные области
То, какой аллокатор выбрать — зависит от вашего приложения. Но перед этим продумайте систему performance тестов, которая покрывает значительную часть пользовательского железа и пользовательских сценариев, потому что не всегда теория совпадает с практикой
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2🤯2⚡1❤🔥1👍1🤡1
Студенты
Помните я вам писал про пару интерсных вещей, которые произошли в прошлом году? Так вот одна из них заключается в том, что я теперь являюсь практиком по C++ у студентов ПМИ ФКН НИУ ВШЭ☺️ . Мне кажется это классная возможность прокачать свои софт скиллы, поработать с множеством людей и возможность вглянуть на обыденные вещи свежим взглядом 🤔 .
Сегодня были мои первые практики. И это было очень интересно. Я совсем забыл про то, что множество элементарных для меня вещей вообще непонятны большинству. И оно понятно: вокруг меня практически всегда профессионалы, с которыми мы общаемся на рабочие темы. А с остальными ребятами я не разговариваю про разработку😐
Пока я только начинаю свыкаться с новым образом на себе, но при этом, конечно же, уже много мыслей о самом процессе: с одной стороны не стоит жестить, с другой стороны мягким быть тоже плохо; с одной стороны хочется рассказать подробнее про одно, но тогда можно не успеть всё🙃 .
В общем, пока всё классно! Думаю, напишу еще постик о преподавании после того, как подойдем к финалу. Глянем, как изменятся мои взгляды на всё это!
Помните я вам писал про пару интерсных вещей, которые произошли в прошлом году? Так вот одна из них заключается в том, что я теперь являюсь практиком по C++ у студентов ПМИ ФКН НИУ ВШЭ
Сегодня были мои первые практики. И это было очень интересно. Я совсем забыл про то, что множество элементарных для меня вещей вообще непонятны большинству. И оно понятно: вокруг меня практически всегда профессионалы, с которыми мы общаемся на рабочие темы. А с остальными ребятами я не разговариваю про разработку
Пока я только начинаю свыкаться с новым образом на себе, но при этом, конечно же, уже много мыслей о самом процессе: с одной стороны не стоит жестить, с другой стороны мягким быть тоже плохо; с одной стороны хочется рассказать подробнее про одно, но тогда можно не успеть всё
В общем, пока всё классно! Думаю, напишу еще постик о преподавании после того, как подойдем к финалу. Глянем, как изменятся мои взгляды на всё это!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13❤4🤡1🐳1
О важности инструментов
В своей жизни я слушал несколько раз курсы по одним и тем же языкам программирования🤪 . Это были 🤓 , но сейчас о другом.
На днях я читал интересный пост в котором автор ставит перед собой задачу добавить
Для простоты я всегда представляю указатель на функцию как номер телефона мастера (например, сантехника): вы звоните ему, говорите что сделать, он делает.
В современном🤔
Я посещаю инструменты, о которых мне рассказали на одном из курсов по🙃 .
Одной из магий
Собственно если зайти и посмотреть, как происходит магия компилятора для предложенного автором кода, то даже новичок, который недавно узнал, что такое шаблоны в☺️ . А проблема в том, что автор сделал кодогенерацию настолько большой, что она может расти неимоверно сильно.
Без инструмента нужно всё равно подумать, даже если опыт есть. А инструмент тебе приносит готовый результат очень быстро: тем самым можно потратить время на что-то другое, не менее полезное🔼 .
В своей жизни я слушал несколько раз курсы по одним и тем же языкам программирования
C++, Python, SQL, и т.д. И если в первый раз я посещал пары для того, чтобы понять какие-то основы и хитрости этих инструментов, то в следующие разы для меня важно было ознакомиться с инфраструктурой вокруг языка: инструменты для анализа, кодогенераторы, различные профилировщики и т.п. Я всё еще так скажем в начале этого пути (как мне кажется) На днях я читал интересный пост в котором автор ставит перед собой задачу добавить
runtime контекста для указателей на функции. Для простоты я всегда представляю указатель на функцию как номер телефона мастера (например, сантехника): вы звоните ему, говорите что сделать, он делает.
Runtime контекст — это когда я не просто даю вам номерок мастера, а еще предупреждаю мастера о каких-то работах, потому что вам по каким-то причинам сложно ему про эти работы рассказать.В современном
С++ понятно (о чем и пишет автор) как сделать, а вот для C или смеси двух этих языков — не всегда очевидно. И в целом как это делать — это предмет поста автора, а мне вот что было интересно: в конце статьи указывается, что один из способов растит размер программы очень сильно. Мне сходу понятно, в чем проблема: я уже видел много такого. А что делать новичку? И что я вообще делаю в таких случаях, даже если уверен, что происходит? Я посещаю инструменты, о которых мне рассказали на одном из курсов по
C++. Считаю, это просто must have инструменты для любого C++ разработчика. Это godbolt.org и cppinsights.io. Первый позволяет смотреть на дизассемблер кода, второй — позволяет поглядеть на код, после того, как компилятор сделает с ним множество магических штук Одной из магий
С++ компилятора является инстациация шаблонов, т.е. в некотором роде подстановка типов. Мы пишем шаблон, который должен работать для определенного набора типов (базово — для всех). После того, как мы используем шаблон в коде, шаблон должен превратиться в код (по аналогии: есть шаблон договора, а есть договор). Собственно если зайти и посмотреть, как происходит магия компилятора для предложенного автором кода, то даже новичок, который недавно узнал, что такое шаблоны в
С++ поймет, в чем же там дело Без инструмента нужно всё равно подумать, даже если опыт есть. А инструмент тебе приносит готовый результат очень быстро: тем самым можно потратить время на что-то другое, не менее полезное
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4☃3👍1🤡1
Оператор "Космический корабль" 🚀
В
Иногда для того, чтобы реализовать этот оператор для структуры с некоторым числом полей, используют функцию👨💻 .
Давайте запишем на
Т.к.😉 .
На днях мы со студентами обсуждали вопрос, а добавляет ли всё же🙃 . У студентов ответ был: вроде как нет?
Я написал бенчмарки для двух компиляторов, где нужно было посортировать структурки (они далеки от идеала, но порядки соотвествуют локальным замерам): GCC и Clang.
В них сравниваются 4 варианта:
🦆
🦆
🦆
🦆
Если глянуть на построенные диаграммы, то есть два любопытных момента:
🤔 На Сlang версия с собственной реализацией работает лучше, нежели чем использовать
🤔 На GCC как-то очень странно себя ведет
Для искушенных читателей приложу сюда Godbolt:
🦆 Clang — генерирует странности и на простом кейсе, когда идет сравнение, и на сложном, когда идет сортировка.
🦆 GCC — с одной стороны кажется, что он прям реально выдает странности, потому что при случае сортировки и внутреннего представления, там вообще не понятный дизассемблерный код, тогда как с внешним оператором — лакончный. У меня есть предположение, судя по тому, что мне удалось прочитать, каким-то чудным действием компилятор все же докидывает свою хитрую магию.
Я подумал, с чем может быть связано такое поведение для☺️ . На GCC теперь дизассмеблерный код стал выглядеть по другому.
Видимо GCC каким-то хитрым способом использует инлайнинг😮 . И делает это замурчательно. Правда его параметры у компилятора настроены не очень, вот GCC и не оптимизирует нашу функцию. Давайте дадим ему рекомендацию:
Вместо
Напишем:
Теперь на GCC все варианты работают примерно одинаково. Но всё равно все они медленнее, если реализовывать сравнение ручками на Clang🤔 . Кажется, что в Clang нужно еще допиливать 🤔 ). Такие вот дела.
Бенчи с изменением: GCC и Clang.
В
С++20 появился новый вид оператора — космический корабль. Выглядит он так: <=>. Это трехстороннее сравнение, которое позволяет в большинстве случаев уменьшить количество кода, который сравнивает два элемента одного типа. Подробнее про мотивацию можно прочитать здесь.Иногда для того, чтобы реализовать этот оператор для структуры с некоторым числом полей, используют функцию
std::tie. Это не просто так: она позволяет создать кортеж ссылок на элементы. А так как у кортежа уже реализован оператор <=>, то остается его всего лишь использовать Давайте запишем на
С++ как это обычно происходит: struct Date {
int year;
int month;
int day;
auto operator<=>(const Date &date) const {
return std::tie(year, month, day) <=> std::tie(date.year, date.month, date.day);
}
};
Т.к.
std::tie создает кортеж ссылок, то после оптимизаций компилятором здесь может вообще не быть кортежа, а просто реализованный оператор, как это бы реализовал программист до существования "космического корабля" На днях мы со студентами обсуждали вопрос, а добавляет ли всё же
std::tie какой-нибудь нагрузки на наше железо? Мой ответ был консервативным: скорее всего да Я написал бенчмарки для двух компиляторов, где нужно было посортировать структурки (они далеки от идеала, но порядки соотвествуют локальным замерам): GCC и Clang.
В них сравниваются 4 варианта:
BenchDefault — это если необходимое сравнение реализовывать ручками;BenchTieInside — это если использовать std::tie как я описал выше;BenchTieInsideDefault — это если попросить компилятор самим сгенерировать всё как он считает лучшим;BenchTie — это если реализовывать оператор отдельно от стурктуры.Если глянуть на построенные диаграммы, то есть два любопытных момента:
std::tie;BenchTie — он работает существенно дольше остальных.Для искушенных читателей приложу сюда Godbolt:
Я подумал, с чем может быть связано такое поведение для
BenchTie на GCC и немного погодя решил в опции копилятора докинуть: -finline-limit=0. Грубо говоря, попросить компилятор максимально не инлайнить функции (т.е. встраивать код функции, вместо вызова этой функции) Видимо GCC каким-то хитрым способом использует инлайнинг
Вместо
auto operator<=>(const Date &date1, const Date &date2) {
return std::tie(date1.year, date1.month, date1.day) <=> std::tie(date2.year, date2.month, date2.day);
};Напишем:
inline auto operator<=>(const Date &date1, const Date &date2) {
return std::tie(date1.year, date1.month, date1.day) <=> std::tie(date2.year, date2.month, date2.day);
};
Теперь на GCC все варианты работают примерно одинаково. Но всё равно все они медленнее, если реализовывать сравнение ручками на Clang
std::tie, чтобы он был хорош (или где-то я не прав Бенчи с изменением: GCC и Clang.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3🤡1🌭1
Поиск по архивам
Когда я только пришел в Яндекс, мне поставили несколько интересных и сложных задач. Некоторые из них до сих пор в работе, а часть — уже сделана.
Одной из завершенных задач является реализовать часть функциональности нашей технологии OCR применительно к данным из архивов прошлых веков. В этом проекте было удивительно то, насколько простые идеи оказываются эффективными для столь необычных данных☺️ .
В самом проекте задействовали очень много людей. Все очень сильно старались: что-то ломалось — мы находили баги и исправляли; что-то вызывало ВАУ и мы просто гордились собой🙃 . За время реализации проекта было очень много локальных мемов, очень много неопределенностей и это было реально атмосфера стартапа в рамках большой компании😊 .
Подробнее про то, что наша команда сделала, можно почитать в блоге.
Ну и ссылка на сам проект.
Когда я только пришел в Яндекс, мне поставили несколько интересных и сложных задач. Некоторые из них до сих пор в работе, а часть — уже сделана.
Одной из завершенных задач является реализовать часть функциональности нашей технологии OCR применительно к данным из архивов прошлых веков. В этом проекте было удивительно то, насколько простые идеи оказываются эффективными для столь необычных данных
В самом проекте задействовали очень много людей. Все очень сильно старались: что-то ломалось — мы находили баги и исправляли; что-то вызывало ВАУ и мы просто гордились собой
Подробнее про то, что наша команда сделала, можно почитать в блоге.
Ну и ссылка на сам проект.
Please open Telegram to view this post
VIEW IN TELEGRAM
Хабр
Как Яндекс научился распознавать, что написано в рукописных архивах
Привет, Хабр. Меня зовут Саша, в прошлый раз я рассказывал сообществу про поиск организаций в Яндексе. В этот раз мы вновь поговорим про поиск, но уже совершенно другого рода. Сегодня расскажем про «...
🔥5🤡1🌭1👨💻1
Антон, ты опять всё сломал?
На прошедшей неделе я столкнулся с очень интересным явлением: ошибка точности в числах с плавающей точкой. Как и что это вообще😳 ? Давайте по порядочку.
В компьютере любые числа представляются в виде фиксированного числа битов 🙃. Например, у меня на компьютере целые числа представлены в виде набор из 32 последовательных битов. Вещественные числа также хранятся в виде нулей и единиц, только хитрым образом. Но всё же ограниченным набором битов, а это значит что бесконечные вещественные числа невозможно в полной мере представить на наших компьютерах. Таким образом в наших вычислениях неизбежно будут происходить ошибки из-за округлений. Но только ли из-за этого🤨 ?
В современных процессорах есть различные инструкции, которые позволяют производить вычисления с вещественными числами чуточку быстрее, нежели чем без них, например: AVX, SSE и т.д. Не будем вдаваться в подробности как они работают, нам лишь нужно понимать что для их использования необходимы определенные условия. Для этого компилятор пытается всяческими способами оптимизировать наш код, чтобы удалось использовать эти инструкции: перестановка инструкций местами, использование различных правил расстановки скобок и т.д.😁
Также современные процессоры не то чтобы особо слушаются нас в плане вычисления того или иного кода: они учатся анализировать и предсказывать, что программа будет делать дальше, иногда также перемешивает инструкции местами: всё в рамках законов, без криминала🤣 .
Стечение таких обстоятельств приводит иногда к тому, что я наблюдал на прошедшей неделе. У меня был один большой массив данных над которым проводилась операция свертки. С удивлением обнаружил, что двух моих машинах с разным железом, но одинаковым софтом код выдает разные результаты, что серьезно влияет на итоговый результат. Более того, у моих коллег тоже получаются отличные от моего результаты😳 .
Интересно то, что я получил этот тензор во время квантезации. До квантезации результаты всегда были предсказуемыми и одинаковыми. Получается, что процесс квантезации вносит сильную нестабильность в вычислительный процесс. И получается, что я опять всё сломал🥺 ?
Ну ничего, починим.
На прошедшей неделе я столкнулся с очень интересным явлением: ошибка точности в числах с плавающей точкой. Как и что это вообще
В компьютере любые числа представляются в виде фиксированного числа битов 🙃. Например, у меня на компьютере целые числа представлены в виде набор из 32 последовательных битов. Вещественные числа также хранятся в виде нулей и единиц, только хитрым образом. Но всё же ограниченным набором битов, а это значит что бесконечные вещественные числа невозможно в полной мере представить на наших компьютерах. Таким образом в наших вычислениях неизбежно будут происходить ошибки из-за округлений. Но только ли из-за этого
В современных процессорах есть различные инструкции, которые позволяют производить вычисления с вещественными числами чуточку быстрее, нежели чем без них, например: AVX, SSE и т.д. Не будем вдаваться в подробности как они работают, нам лишь нужно понимать что для их использования необходимы определенные условия. Для этого компилятор пытается всяческими способами оптимизировать наш код, чтобы удалось использовать эти инструкции: перестановка инструкций местами, использование различных правил расстановки скобок и т.д.
Также современные процессоры не то чтобы особо слушаются нас в плане вычисления того или иного кода: они учатся анализировать и предсказывать, что программа будет делать дальше, иногда также перемешивает инструкции местами: всё в рамках законов, без криминала
Стечение таких обстоятельств приводит иногда к тому, что я наблюдал на прошедшей неделе. У меня был один большой массив данных над которым проводилась операция свертки. С удивлением обнаружил, что двух моих машинах с разным железом, но одинаковым софтом код выдает разные результаты, что серьезно влияет на итоговый результат. Более того, у моих коллег тоже получаются отличные от моего результаты
Интересно то, что я получил этот тензор во время квантезации. До квантезации результаты всегда были предсказуемыми и одинаковыми. Получается, что процесс квантезации вносит сильную нестабильность в вычислительный процесс. И получается, что я опять всё сломал
Ну ничего, починим.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🤔2🤬1🤡1🌭1👨💻1
Кажется, взрослею 🤔
На днях столкнулся с выражением, которое меня заставило задуматься на множество часов:
Я стал анализировать свой жизненный путь и подумал, что это возможно одно из самых справедливых утверждений, с которым очень сильно не хочется соглашаться. Ведь можно сделать так много, можно стать профессионалом в огромном числе сфер, просто нужно... постараться😉 . Так ли это?
Я не думаю😔 . Вариативность зачастую лишь усложняет систему, но не делает её лучше. Вы можете изучить 10 профессий, потратить на каждую по полгода, но при этом так и останетесь начинающим специалистом в каждой из них. Вы не станете мастером этого дела. А могли бы (за 5 лет-то) 🙃 .
Да далеко ходить не надо: основной причиной сложности программирования на😂
Будучи разработчиком мне уже пришлось сделать множество отказов, чтобы стать профессиональнее в том, что я считаю наиболее важным. Я писал Web приложения, но в итоге я не Web-разработчик; я писал свой графический движок, но я не стал game developer; я писал хитрые алгоритмы, но я не разработчик структур данных; я обучал нейронки из кучи разных доменов, но сейчас занимаюсь только компьютерным зрением...👨💻
Я отказался от этого всего, хотя мне было интересно. Отказался ради того, чтобы быть тем, кем сейчас являюсь. Наверное, я стал чуточку профессиональнее. Хотя было так много и других потенциалов. Видимо, взрослею.🤔
На днях столкнулся с выражением, которое меня заставило задуматься на множество часов:
Взросление — это отказ от потенциалов, которые возможны. Я стал анализировать свой жизненный путь и подумал, что это возможно одно из самых справедливых утверждений, с которым очень сильно не хочется соглашаться. Ведь можно сделать так много, можно стать профессионалом в огромном числе сфер, просто нужно... постараться
Я не думаю
Да далеко ходить не надо: основной причиной сложности программирования на
C++ считается ручной контроль памяти. Хотя казалось бы — свобода действий. И да, благодаря такому подходу можно более четко контролировать ресурсы, но на деле? Куча кода, который делает то, что в других языках записывается одной строчкой. Непонятные падения приложения, постоянные утечки. Бррр Будучи разработчиком мне уже пришлось сделать множество отказов, чтобы стать профессиональнее в том, что я считаю наиболее важным. Я писал Web приложения, но в итоге я не Web-разработчик; я писал свой графический движок, но я не стал game developer; я писал хитрые алгоритмы, но я не разработчик структур данных; я обучал нейронки из кучи разных доменов, но сейчас занимаюсь только компьютерным зрением...
Я отказался от этого всего, хотя мне было интересно. Отказался ради того, чтобы быть тем, кем сейчас являюсь. Наверное, я стал чуточку профессиональнее. Хотя было так много и других потенциалов. Видимо, взрослею.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤3🤡1