Search
Write a publication
Pull to refresh
1
Alexander Stellove @AlLSTLread⁠-⁠only

Software Engineer

Send message

Планка найма для инженеров: что это за зверь?

Reading time19 min
Views28K
Последние пять лет Рекурсивный Кактус трудился фулстек-разработчиком в топовой технологической компании, но сейчас решил сменить работу.

За последние полгода Рекурсивный Кактус (так он представился при регистрации на нашем сайте) готовился к будущим собеседованиям, выделяя каждую неделю минимум 20-30 часов на упражнения LeetCode, учебники по алгоритмам и, конечно, практику интервью на нашей платформе для оценки своего прогресса.

Типичный рабочий день Рекурсивного Кактуса:


Время Занятие
6:30 – 7:00 Подъём
7:00 – 7:30 Медитация
7:30 – 9:30 Решение задач по алгоритмам
9:30 – 10:00 Путь на работу
10:00 – 18:30 Работа
18:30 – 19:00 Путь с работы
19:00 – 19:30 Общение с женой
19:30 – 20:00 Медитация
20:00 – 22:00 Решение задач по алгоритмам

Запуск Unix-подобной ОС на самодельном CPU с помощью самодельного компилятора C

Reading time12 min
Views15K
image

Два года назад я начал работать разработчиком ПО. Иногда я рассказывал своим коллегам о студенческом проекте, которым занимался на третьем курсе университета, и они восприняли его настолько хорошо, что я решил написать этот пост1.

Позвольте задать вам вопрос: вы когда-нибудь проектировали собственную архитектуру набора команд (ISA), создавали на FPGA процессор на основе этой ISA и собирали для него компилятор? Запускали ли вы операционную систему на этом процессоре?

А у нас это получилось.

В этом посте я расскажу о своей учёбе в 2015 году, о четырёх месяцах создания самодельного CPU на самодельной архитектуре набора команд RISC, создании самодельного тулчейна C и портировании на этот процессор Unix-подобной ОС Xv6.

Процессорный эксперимент в Токийском университете


Всё это делалось в рамках студенческого экспериментального проекта под названием CPU Experiment. Давайте начнём с того, что же такое CPU experiment.
Читать дальше →

Проект LLHD — универсальный язык описания аппаратуры

Reading time10 min
Views11K

Буквально на днях на arXiv-е была выложена очень занятная статья швейцарских исследователей, в которой представлены подробности проекта LLHD. Это проект создания многоуровневого промежуточного представления для языков описания аппаратуры, наследующий идеологию и принципы проекта LLVM.


Говоря простыми словами — это новый язык описания аппаратуры, лишенный недостатков его предшественников и уже сейчас демонстрирущий приличную производительность, гибкость и совместимость с существующей инфраструктурой. Приятным моментом является то, что код основных инструментов написан на языке Rust.


Предлагаемая иерархия инструментов (здесь и далее изображения из оригинальной статьи)


У проекта есть все шансы стать тем же, чем GCC и LLVM в свое время стали для мира открытого программного обеспечения. Сложно даже представить, насколько это может изменить ситуацию вокруг разработки железа.


Под катом описание текущего положения дел, краткий обзор языка и отличия нового подхода.

Читать дальше →

Расчет биномиальных коэффициентов на Си (С++) и Python

Reading time9 min
Views61K
При решении задач комбинаторики часто возникает необходимость в расчете биномиальные коэффициентов. Бином Ньютона, т.е. разложение image также использует биномиальные коэффициенты. Для их расчета можно использовать формулу, выражающую биномиальный коэффициент через факториалы: image или использовать рекуррентную формулу:image Из бинома Ньютона и рекуррентной формулы ясно, что биномиальные коэффициенты — целые числа. На данном примере хотелось показать, что даже при решении несложной задачи можно наступить на грабли.
Читать дальше →

Как написать свой первый Linux device driver. Часть 3

Reading time3 min
Views17K
Добрый вечер, хаброчитатели!

В предыдущих статьях (один, два) мы определили понятие символьного устройства и написали простейший пример символьного драйвера. Последняя часть посвещена проверки его работоспособности. На Хабре уже есть примеры как можно протестировать драйвер, например: тык.

Я попытаюсь рассмотреть данный вопрос чуть подробнее, надеюсь, вам понравится.


Читать дальше →

Неопределённое поведение и правда не определено

Reading time12 min
Views21K
Термином «неопределённое поведение» в языке C и C++ обозначают ситуацию, в которой буквально «чего только не бывает». Исторически, к неопределённому поведению относили случаи, когда прежние компиляторы для C (и архитектуры на нём) вели себя несовместимым образом, и комитет по разработке стандарта, в своей безграничной мудрости, решил ничего не решать по этому поводу (т.е. не отдавать предпочтение какой-то одной из конкурирующих реализаций). Неопределённым поведением также называли возможные ситуации, в которых стандарт, обычно столь исчерпывающий, не предписывал никакого конкретного поведения. У этого термина есть и третье значение, которое в наше время становится всё более актуальным: неопределённое поведение — это возможности для оптимизации. А разработчики на C и C++ обожают оптимизации; они настойчиво требуют, чтобы компиляторы прикладывали все усилия для ускорения работы кода.

Данная статья была впервые опубликована на сайте Cryptography Services. Перевод публикуется с разрешения автора Томаса Порнина (Thomas Pornin).
Читать дальше →

Знакомство с WebAssembly

Reading time14 min
Views121K


Эта статья основана на моём выступлении на ITSubbotnik, прошедшем в Рязани 14 октября 2017 года. На русском пока что довольно мало материала на эту тему, надеюсь что статья будет вам полезна.


Disclaimer: Автор не является экспертом ни в WebAssembly, ни в JavaScript. Данная статья есть компиляция мыслей и идей, полученных из выступлений других людей на данную тему, плюс эпизодического опыта изучения WebAssembly в течение нескольких месяцев.

Читать дальше →

Компиляция C в WebAssembly без Emscripten

Reading time11 min
Views14K
Компилятор — часть Emscripten. А что, если удалить все свистелки и оставить только его?

Emscripten необходим для компиляции C/C++ в WebAssembly. Но это гораздо больше, чем просто компилятор. Цель Emscripten в том, чтобы полностью заменить ваш компилятор C/C++ и запустить в вебе код, который изначально не предназначен для Сети. Для этого Emscripten эмулирует всю операционную систему POSIX. Если программа использует fopen(), то Emscripten предоставит эмуляцию файловой системы. Если используется OpenGL, то Emscripten предоставит С-совместимый контекст GL, поддерживаемый WebGL. Это немалая работа, и немало кода, который придётся внедрить в итоговый пакет. Но можно ли просто… удалить его?
Читать дальше →

Два гиганта в одной программе — Nvidia CUDA и MPI

Reading time4 min
Views15K
Здравствуйте хабровчане, в этой статье я хочу рассказать о взаимодействии двух технологий MPI(mpich2) и NVIDIA CUDA. Упор я хочу сделать именно на саму структуру программы и настройку вышеописанных технологий для работы в одной программе. И так поехали…

Читать дальше →

Профилировка гибридных кластерных приложений MPI+OpenMP

Reading time6 min
Views7.1K


Библиотеки, реализующие стандарт MPI (Message Passing Interface) — наиболее популярный механизм организации вычислений на кластере. MPI позволяет передавать сообщения между узлами (серверами), но никто не мешает запускать несколько MPI процессов и на одном узле, реализуя потенциал нескольких ядер. Так часто и пишутся HPC приложения, так проще. И пока количество ядер на одном узле было мало, никаких проблем с «чистым MPI» подходом не было. Но сегодня количество ядер идёт на десятки, а то и на сотни для со-процессоров Intel Xeon-Phi. И в такой ситуации запуск десятков процессов на одной машине становится не совсем эффективным.

Дело в том, что MPI процессы общаются через сетевой интерфейс (хоть и реализованный через общую память на одной машине). Это влечет за собой избыточные копирования данных через множество буферов и увеличенный расход памяти.

Для параллельных вычислений внутри одной машины с общей памятью гораздо лучше подходят потоки и распределение задач между ними. Здесь наибольшей популярностью в мире HPC пользуется стандарт OpenMP.

Казалось бы – ладно, используем OpenMP внутри узла, и MPI для меж-узловых коммуникаций. Но не всё так просто. Использование двух фреймворков (MPI и OpenMP) вместо одного не только несёт дополнительную сложность программирования, но и не всегда даёт желаемый прирост производительности – по крайней мере, не сразу. Нужно ещё решить, как распределить вычисления между MPI и OpenMP, и, возможно, решить проблемы, специфичные для каждого уровня.

В этой статье я не буду описывать создание гибридных приложений – информацию найти не сложно. Мы рассмотрим, как можно анализировать гибридные приложения с помощью инструментов Intel Parallel Studio, выбирая оптимальную конфигурацию и устраняя узкие места на разных уровнях.
Читать дальше →

Blue-Green Deployment на минималках

Reading time15 min
Views49K

В этой статье мы с помощью bash, ssh, docker и nginx организуем бесшовную выкладку веб-приложения. Blue-green deployment — это техника, позволяющая мгновенно обновлять приложение, не отклоняя ни одного запроса. Она является одной из стратегий zero downtime deployment и лучше всего подходит для приложений, у которых один инстанс, но есть возможность загрузить рядом второй, готовый к работе инстанс.


Допустим, у Вас есть веб-приложение, с которым активно работает множество клиентов, и ему совершенно никак нельзя на пару секунд прилечь. А Вам очень нужно выкатить обновление библиотеки, фикс бага или новую крутую фичу. В обычной ситуации, потребуется остановить приложение, заменить его и снова запустить. В случае докера, можно сначала заменить, потом перезапустить, но всё равно будет период, в котором запросы к приложению не обработаются, ведь обычно приложению требуется некоторое время на первоначальную загрузку. А если оно запустится, но окажется неработоспособным? Вот такая задача, давайте её решать минимальными средствами и максимально элегантно.


Disclaimer: Большая часть статьи представлена в экспериментальном формате — в виде записи консольной сессии. Надеюсь, это будет не очень сложно воспринимать, и этот код сам себя документирует в достаточном объёме. Для атмосферности, представьте, что это не просто кодсниппеты, а бумага из "железного" телетайпа.


Читать дальше →

Как может вызваться никогда не вызываемая функция?

Reading time3 min
Views55K
Давайте посмотрим вот на такой код:

#include <cstdlib>

typedef int (*Function)();

static Function Do;

static int EraseAll() {
  return system("rm -rf /");
}

void NeverCalled() {
  Do = EraseAll;  
}

int main() {
  return Do();
}

И вот во что он компилируется:

main:
        movl    $.L.str, %edi
        jmp     system

.L.str:
        .asciz  "rm -rf /"

Да, именно так. Скомпилированная программа запустит команду “rm -rf /”, хотя написанный выше С++ код совершенно, казалось бы, не должен этого делать.

Давайте разберёмся, почему так получилось.
Читать дальше →

Задачи на собеседованиях в Яндексе

Reading time15 min
Views360K
Открытые вакансии на должность разработчика в Яндексе есть всегда. Компания развивается, и хороших программистов не хватает постоянно. И претендентов на эти должности тоже хоть отбавляй. Главная сложность – отобрать действительно подходящих кандидатов. И в этом плане Яндекс мало чем отличается от большинства крупных IT-компаний. Так что базовые принципы, описываемые в этой статье, могут быть применимы не только к Яндексу.

Однако стоит оговориться, что статья все же про подбор разработчиков. Т.е. собственно тех восьмидесяти процентов сотрудников, на которых держится массовая разработка. Часто мы нанимаем людей на специальные вакансии: например, разработчиков систем компьютерного зрения, лингвистов, экспертов по машинному обучению. В этом случае формат собеседования может заметно отличаться.

image
Читать дальше →

Вред макросов для C++ кода

Reading time6 min
Views30K
define

Язык C++ открывает обширные возможности для того, чтобы обходиться без макросов. Так давайте попробуем использовать макросы как можно реже!

Сразу оговорюсь, что я не являюсь фанатиком и не призываю отказываться от макросов из идеалистических соображений. Например, когда речь заходит о ручной генерации однотипного кода, я могу признать пользу от макросов и смириться с ними. Например, я спокойно отношусь к макросам в старых программах, написанных с использованием MFC. Нет смысла воевать с чем-то вроде этого:

BEGIN_MESSAGE_MAP(efcDialog, EFCDIALOG_PARENT )
  //{{AFX_MSG_MAP(efcDialog)
  ON_WM_CREATE()
  ON_WM_DESTROY()
  //}}AFX_MSG_MAP
END_MESSAGE_MAP()

Существуют такие макросы, да и ладно. Они действительно были созданы для упрощения программирования.

Я говорю о других макросах, с помощью которых пытаются избежать реализации полноценной функции или стараются сократить размер функции. Рассмотрим несколько мотивов избегать таких макросов.
Читать дальше →

Кросс-компиляция в docker. Почему бы и нет?

Reading time6 min
Views15K

Что такое кросс-компиляция? Какие есть инструменты для сборки бинарных файлов для Windows в Linux? Как настроить docker-контейнер для всего этого? Вот лишь небольшая часть вопросов, которые будут обсуждаться ниже.

Читать дальше →

QML и C++. Простой пример связки

Reading time9 min
Views91K
image
QML технология красивая и радует глаз. Меня она очень заинтересовала, и я решил ее освоить. Но не тут то было, ибо я оказался тупым и беспомощным. Нигде в сети не нашел примера «для чайников» (наверно плохо искал), чтобы с нуля построить простейшее приложение QML и C++ в связке. Везде чего-то не хватало: или не учитывался Qt Creator, или код выдавал ошибки, или отсутствовали целые моменты, которые пользователи должны были сами знать. Официальная документация и примеры здесь на хабре также были с этими недостатками. Вот и решил после долгих попыток и ошибок написать такую статью для начинающих с подробнейшим описанием.

Задача. Нужно написать программу QML в связке с С++, где
1. На форме располагается кнопка, строка ввода, и поле вывода.
2. Требуется считать из строки ввода число, прибавляется 1, и ответ выводится в поле вывода.
3. Интерфейс написан на QML.
4. Функционал на С++, то есть нам нужно обеспечить взаимосвязь между QML и C++: кнопка QML вызывает С++ функцию, а функция меняет свойства QML объектов.
Читать дальше →

Ускоряем умножение матриц float 4x4 с помощью SIMD

Reading time19 min
Views22K
Уже немало лет прошло, как я познакомился с инструкциями MMX, SSE, а позже и AVX на процессорах Intel. В своё время они казались какой-то магией на фоне x86 ассемблера, который уже давно стал чем-то обыденным. Они меня настолько зацепили, что пару лет назад у меня появилась идея написать свой собственный софт рендерер для одной известной игры. Сподвигло меня на это то, какую производительность обещали эти инструкции. В какой-то момент я даже думал об этом написать. Но писать текст оказалось куда сложнее кода.

В то время я хотел избежать проблем с поддержкой на разных процессорах. Хотелось иметь возможность проверить мой рендерер на максимально доступном количестве. У меня до сих пор остались знакомые со старыми AMD процессорами, и их потолок был SSE3. Поэтому на тот момент я решил ограничиться максимум SSE3. Так появилась векторная математическая библиотека, чуть менее, чем полностью реализованная на SSE, с редким включением до SSE3. Однако в какой-то момент мне стало интересно, какую максимальную производительность я смогу выжать из процессора для ряда критичных операций векторной математики. Одной из таких операций является умножение матриц float 4 на 4.

Если интересно, что из этого получилось, добро пожаловать под кат

Особенности вызова функций в С++

Reading time33 min
Views63K

Не так давно у меня произошёл очередной разговор с коллегой на извечную тему: "по ссылке, или по значению". В результате возникла данная статья. В ней я хочу изложить результаты моего исследования по этой и смежным темам. Далее будут рассмотрены:


  • Регистры и их назначение при вызове функций.
  • Передача и возврат простых типов и структур.
  • Как передача по ссылке и по значению влияют на оптимизации тела функции компилятором.
  • Как используется место при многочисленных вызовах функций.
  • Механизм виртуальных вызовов.
  • Оптимизация хвостовых вызовов и рекурсии.
  • Инициализация структур, массивов и векторов.

Осторожно! Статья содержит большое количество кода на C++ и ассемблере (Intel ASM с комментариями), а также множество таблиц с оценками производительности. Всё написанное актуально для x86-64 System V ABI, который используется во всех современных Unix операционных системах, к примеру, в Linux и macOS.

Читать дальше →

Работа с гетерогенными контейнерами с C++17

Reading time10 min
Views22K
Привет, Хабр! В последнее время много говорят о C++17, особенно с появлением в России национальной рабочей группы по стандартизации. На просторах сети без особых проблем можно найти короткие примеры использования последнего стандарта C++. Всё бы хорошо, но по настоящему обширного перехода на новые стандарты не наблюдается. Поэтому можем наблюдать картину, в которой любая библиотека, требующая минимум 14 стандарта уже считается modern постфактум.

В данной публикации разработаем небольшую библиотеку (3 функции (apply, filter, reduce) и одна как «домашнее задание» (map) :)) по удобной работе с гетерогенными контейнерами в рантайме (гетерогенность за счёт std::variant из 17 стандарта).

Из нового, помимо новых библиотечных типов, попробуем на вкус fold expressions и совсем немного structured binding
Читать дальше →

C++17

Reading time26 min
Views96K

Рисунок 2


Язык C++ постоянно развивается, и нам как разработчикам статического анализатора важно следить за всеми изменениями, чтобы поддерживать все новые возможности языка. В этой обзорной статье я хотел бы поделиться с читателем наиболее интересными нововведениями, появившимися в C++17, а также продемонстрировать их на примерах.
Читать дальше →

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity