Обновить
128K+

C++ *

Типизированный язык программирования

255,08
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

Методы наименьших квадратов без слёз и боли

Время на прочтение10 мин
Охват и читатели54K


Итак, очередная статья из цикла «математика на пальцах». Сегодня мы продолжим разговор о методах наименьших квадратов, но на сей раз с точки зрения программиста. Это очередная статья в серии, но она стоит особняком, так как вообще не требует никаких знаний математики. Статья задумывалась как введение в теорию, поэтому из базовых навыков она требует умения включить компьютер и написать пять строк кода. Разумеется, на этой статье я не остановлюсь, и в ближайшее же время опубликую продолжение. Если сумею найти достаточно времени, то напишу книгу из этого материала. Целевая публика — программисты, так что хабр подходящее место для обкатки. Я в целом не люблю писать формулы, и я очень люблю учиться на примерах, мне кажется, что это очень важно — не просто смотреть на закорючки на школьной доске, но всё пробовать на зуб.

Итак, начнём. Давайте представим, что у меня есть триангулированная поверхность со сканом моего лица (на картинке слева). Что мне нужно сделать, чтобы усилить характерные черты, превратив эту поверхность в гротескную маску?



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

C++: сеанс спонтанной археологии и почему не стоит использовать вариативные функции в стиле C

Время на прочтение18 мин
Охват и читатели26K
Началось все, как водится, с ошибки. Я первый раз работал с Java Native Interface и делал в C++ части обертку над функцией, создающей Java объект. Эта функция — CallVoidMethod — вариативна, т.е. помимо указателя на среду JNI, указателя на тип создаваемого объекта и идентификатора вызываемого метода (в данном случае конструктора), она принимает произвольное число других аргументов. Что логично, т.к. эти другие аргументы передаются вызываемому методу на стороне Java, а методы могут быть разные, с разным числом аргументов любых типов.

Соответственно и свою обертку я тоже сделал вариативной. Для передачи произвольного числа аргументов в CallVoidMethod использовал va_list, потому что по-другому в данном случае никак. Да, так и отправил va_list в CallVoidMethod. И уронил JVM банальным segmentation fault.

За 2 часа я успел перепробовать несколько версий JVM, от 8-ой до 11-ой, потому что: во-первых это мой первый опыт с JVM, и в этом вопросе я StackOverflow доверял больше, чем себе, а во-вторых кто-то на StackOverflow посоветовал в таком случае использовать не OpenJDK, а OracleJDK, и не 8, а 10. И лишь потом я наконец заметил, что помимо вариативной CallVoidMethod есть CallVoidMethodV, которая произвольное число аргументов принимает через va_list.

Что мне больше всего не понравилось в этой истории, так это то, что я не сразу заметил разницу между эллипсисом (многоточием) и va_list. А заметив, не смог объяснить себе, в чем принципиальное отличие. Значит, надо разобраться и с эллипсисом, и с va_list, и (поскольку речь все-таки о C++) с вариативными шаблонами.
Читать дальше →

Learn OpenGL. Урок 6.4 – IBL. Зеркальная облученность

Время на прочтение26 мин
Охват и читатели24K
OGL3
В предыдущем уроке мы подготовили нашу модель PBR для работы вместе с методом IBL – для этого нам потребовалось заранее подготовить карту облученности, которая описывает диффузную часть непрямого освещения. В этом уроке мы обратим внимание на вторую часть выражения отражающей способности – зеркальную:

$L_o(p,\omega_o) = \int\limits_{\Omega} (k_d\frac{c}{\pi} + k_s\frac{DFG}{4(\omega_o \cdot n)(\omega_i \cdot n)}) L_i(p,\omega_i) n \cdot \omega_i d\omega_i$


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

Стример из MiniDV-видеокамеры

Время на прочтение4 мин
Охват и читатели18K
Иногда может захотеться странного. Вот вроде бы лежит себе видеокамера стандарта MiniDV и лежит. Есть не просит. А что если взять и записать на её кассеты вовсе даже не видео, а, скажем, файлы. Запись-то всё равно цифровая. Пусть объём кассеты всего лишь около 13 ГБ (под данные получилось занять около 9.5 ГБ), пусть скорость чтения 3.5 МБ в секунду, но ведь получится простой домашний стример. Так сказать, “стример для бедных”. Почему бы не отправить на несколько кассет, скажем, какие-либо важные файлы. Просто так, на всякий случай. Попробуем!
Читать дальше →

Современный C++ != (Самый)Новый Стандарт

Время на прочтение4 мин
Охват и читатели25K


Термин «современный C++» часто используется как синоним выражения «код, использующий новый стандарт C++». Здесь «новый» может означать что угодно от C++11 до C++17, или даже то, что уже сейчас доступно из C++20. Я думаю, что современный C++ — это нечто большее, не ограничивающееся добавлением флага -std=c++17.
Читать дальше →

«Не надо скромничать. Пробуй!». Интервью о жизни, компиляторах и жизни в компиляторах с Alexandre Mutel из Unity

Время на прочтение20 мин
Охват и читатели6.9K
Как добиться успеха в системном программировании, что нужно знать и понимать, особенно если ты работаешь уже третий десяток лет? C# и перформанс — cтоит ли переписывать на C# всё что видишь? Какое будущее в смысле низкоуровневых компиляторных технологий нас ждёт?

Сегодня в нашей виртуальной студии на вопросы отвечает Alexandre Mutel.

Alexandre Mutel работает на должности Lead Software Architect в Unity Technologies. Кроме того, он известный в опенсорсе разработчик, контрибутящий в SharpDX, Markdig, Zio и другие проекты, а с 2014 года — MVP в категории «Visual Studio and Development Technologies».

Alexandre работает над разными низкоуровневыми и высокоуровневыми вопросами в областях рендеринга графики в реальном времени, GPGPU, синтеза звука, эффективного использования и архитектуры управляемых языков, кодогенерации и документации.

Как всегда, интервью ведут Евгений Трифонов (phillennium) и Олег Чирухин (olegchir) из JUG.ru Group.



В конце поста есть сюрприз от Дилана Битти (другого известного дотнетчика) — мы и сами не ожидали.

Как мы перевели 10 миллионов строк кода C++ на стандарт C++14 (а потом и на C++17)

Время на прочтение7 мин
Охват и читатели52K
Некоторое время назад (осенью 2016), при разработке очередной версии технологической платформы 1С:Предприятие внутри команды разработки встал вопрос о поддержке нового стандарта C++14 в нашем коде. Переход на новый стандарт, как мы предполагали, позволил бы нам писать многие вещи элегантней, проще и надежней, упрощал поддержку и сопровождение кода. И в переводе вроде бы нет ничего экстраординарного, если бы не масштабы кодовой базы и специфические особенности нашего кода.

Для тех кто не знает, 1С:Предприятие – это среда для быстрой разработки кросс-платформенных бизнес-приложений и runtime для их выполнения в разных ОС и СУБД. В общих чертах в состав продукта входят:


Мы стараемся по максимуму писать один код для разных ОС — кодовая база сервера общая на 99%, клиента — примерно на 95%. Технологическая платформа 1С:Предприятие преимущественно написана на C++ и ниже приведены приблизительные характеристики кода:

  • 10 миллионов строк С++ кода,
  • 14 тысяч файлов,
  • 60 тысяч классов,
  • полмиллиона методов.

И все это хозяйство надо было перевести на C++14. О том, как мы это делали и с чем столкнулись в процессе, мы сегодня и расскажем.

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

В трёх статьях о наименьших квадратах: ликбез по теории вероятностей

Время на прочтение10 мин
Охват и читатели24K
Полтора года назад я опубликовал статью «Математика на пальцах: методы наименьших квадратов», которая получила весьма приличный отклик, который, в том числе, заключался в том, что я предложил нарисовать сову. Ну, раз сова, значит, нужно объяснять ещё раз. Через неделю ровно на эту тему я начну читать несколько лекций студентам-геологам; пользуюсь случаем, излагаю тут (адаптированные) основные тезисы в качестве черновика. Моей основной целью не является дать готовый рецепт из книги о вкусной и здоровой пищи, но рассказать, почему он таков и что ещё находится в соответствующем разделе, ведь связи между разными разделами математики — это самое интересное!

На данный момент я предполагаю разбить текст следующим образом:


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

Насколько обоснован теорвер или верите ли вы в теорию эволюции?


Однажды мне задали вопрос, верю ли я в теорию эволюции. Прямо сейчас сделайте паузу, подумайте, как вы на него ответите.


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

The Kernel-Bridge Framework: мостик в Ring0

Время на прочтение7 мин
Охват и читатели10K
Хотели ли Вы когда-нибудь заглянуть под капот операционной системы, посмотреть на внутреннее устройство её механизмов, покрутить винтики и посмотреть на открывшиеся возможности? Возможно, даже хотели поработать напрямую с железом, но считали, что драйвера — rocketscience?

Предлагаю вместе пройтись по мостику в ядро и посмотреть, насколько глубока кроличья нора.

Итак, представляю драйвер-фреймворк для kernel-хакинга, написанный на C++17, и призванный, по возможности, снять барьеры между ядром и юзермодом или максимально сгладить их присутствие. А также, набор юзермодных и ядерных API и обёрток для быстрой и удобной разработки в Ring0 как для новичков, так и для продвинутых программистов.

Основные возможности:

  • Доступ к портам ввода-вывода, а также проброс инструкций in, out, cli и sti в юзермод через IOPL
  • Обёртки над системной пищалкой
  • Доступ к MSR (Model-Specific Registers)
  • Набор функций для доступа к юзермодной памяти других процессов и к памяти ядра
  • Работа с физической памятью, DMI/SMBIOS
  • Создание юзермодных и ядерных потоков, доставка APC
  • Юзермодные Ob*** и Ps***-каллбэки и фильтры файловой системы
  • Загрузка неподписанных драйверов и ядерных библиотек

… и многое другое.
Читать дальше →

Полёт свиньи, или Оптимизация интерпретаторов байт-кода

Время на прочтение13 мин
Охват и читатели22K


"No matter how hard you try, you can't make a racehorse out of a pig. You can, however, make a faster pig" (комментарий в исходном коде Емакса)

Всем известен тот факт, что свиньи не летают. Не менее популярно мнение о том, что интерпретаторы байт-кодов как техника исполнения языков высокого уровня не поддаются ускорению без применения трудоёмкой динамической компиляции.


Во второй части серии статей об интерпретаторах байт-кодов я на примере небольшой стековой виртуальной машины ПВМ («Поросячья Виртуальная Машина») постараюсь показать, что не всё потеряно для трудолюбивых поросят с амбициями и что в рамках (в основном) стандартного C вполне возможно ускорить работу таких интерпретаторов по меньшей мере в полтора раза.

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

Четыре года развития SObjectizer-5.5. Как SObjectizer изменился за это время?

Время на прочтение22 мин
Охват и читатели1.5K
Первая версия SObjectizer-а в рамках ветки 5.5 вышла чуть больше четырех лет назад — в начале октября 2014-го года. А сегодня увидела свет очередная версия под номером 5.5.23, которая, вполне возможно, закроет историю развития SObjectizer-5.5. По-моему, это отличный повод оглянуться назад и посмотреть, что же было сделано за минувшие четыре года.

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

Возможно, кому-то такой рассказ будет интересен с точки зрения археологии. А кого-то, возможно, удержит от такого сомнительного приключения, как разработка собственного акторного фреймворка для C++ ;)
Читать дальше →

Проблемные аспекты программирования на С++

Время на прочтение28 мин
Охват и читатели16K

В С++ достаточно много особенностей, которые можно считать потенциально опасными — при просчетах в проектировании или неаккуратном кодировании они легко могут привести к ошибкам. В статье приводится подборка таких особенностей, даны советы, как уменьшить их негативное влияние.



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

Работа со строками на этапе компиляции в современном C++

Время на прочтение20 мин
Охват и читатели35K


Если вы программируете на C++, то наверняка задавались вопросом почему нельзя сравнить два строковых литерала или выполнить их конкатенацию:


auto str = "hello" + "world"; // ошибка компиляции

if ("hello" < "world") { // компилируется, но работает не так, как ожидалось
    // ...
}

Впрочем, как говорится, "нельзя, но если очень хочется, то можно". Ломать стереотипы будем под катом, причем прямо на этапе компиляции.

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

Ближайшие события

Интересная задачка на С

Время на прочтение2 мин
Охват и читатели9.6K

Просматривая протоколы собеседований на позицию разработчика, обнаружил такую задачу: "Предложите код, который бы выводил на печать числа в убывающем порядке от n до 0, не используя (скрыто или явно) операторы сравнения (реализация функции вывода на печать не в счет)". Несмотря на то, что ко мне эта задача не имела отношения, она меня заняла и я решил подумать над способами ее решения (хотя, кому и при решении какой задачи может понадобиться такой метод оптимизации кода, мне осталось неизвестно, но тем не менее ).


Первое, что пришло на ум, — попытаться использовать шаблоны. Например так


template<int n> 
void print()
{
    printf("%d\n", n);
    print<n - 1>();
}

template<>
void print<0>()
{
    printf("0\n");
}

int main(int argc, char* argv[])
{
    print<N>();
    return 0;
}

Проблема в том, что программирование это инженерная дисциплина, а не оккультная, и если "что-то" должно в системе происходить, то "оно" должно быть описано и под это должны быть выделены ресурсы, и в данном случае, поскольку отработка шаблонов происходит на этапе компиляции, есть ограницения на вложенность подобного рода конструкций (и это хорошо и правильно, и Слава Богу, что так есть), и компилятор совершенно справедливо выдал "fatal error C1202: recursive type or function dependency context too complex" при размере N больше 2000.

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

3 книги по C++ 17 (на английском)

Время на прочтение2 мин
Охват и читатели11K
Сегодня мы рассказываем вам о трех книгах, написанных нашими Microsoft MVP, по C++ 17. Они могут быть хорошими отправными точками в пути ознакомления с новой версией этого языка программирования. Все они продаются в электронном и бумажном виде на онлайн площадках (от €8.64 до $42.99 за электронные версии).

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

JsonWriterSax — библиотека для создания JSON

Время на прочтение5 мин
Охват и читатели3.9K

Некоторое время назад я писал приложение на c++/Qt, которое отправляло по сети большие объемы данных в формате JSON. Использовался стандартный QJsonDocument. При внедрении столкнулся с низкой производительностью, а также неудобным дизайном классов, который не позволял нормально детектировать ошибки при работе. В результат появилась библиотека JsonWriterSax, позволяющая писать JSON документы в SAX стиле с высокой скоростью, которую и публикую на github.com под лицензией MIT. Кому интересно — прошу под кат.

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

«Lock-free, or not lock-free, that is the question» или «Здоровый сон хуже горькой редьки»

Время на прочтение7 мин
Охват и читатели7.7K

На написание данной статьи меня подвигли комментарии к статье "Как правильно и неправильно спать".


Речь в данной статье пойдёт о разработке многопоточных приложений, применимости lock-free к некоторым кейсам возникшим в процессе работы над LAppS, о функции nanosleep и насилии над планировщиком задач.


NB: Всё обсуждаемое касается разработки на C++ под Linux, но может быть применимо ко всем POSIX.1-2008 совместимым системaм (с оглядкой на конкретную реализацию).

Вобщем всё довольно сумбурно, надеюсь ход мысли в изложении будет понятен. Если интересно то прошу под кат.

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

Портирование COM на Linux

Время на прочтение4 мин
Охват и читатели20K
Мне нравится технология COM. Но речь пойдет не о технологии, восхвалении или недостатках COM, а опыте переноса и реализации на Linux. Велосипед? Целесообразность?
Читать дальше →

Как правильно и неправильно спать

Время на прочтение7 мин
Охват и читатели30K
Не так давно мимо нас пробегала неплохая статья об ужасном состоянии производительности современного ПО (оригинал на английском, перевод на Хабре). Эта статья напомнила мне об одном антипаттерне кода, который встречается весьма часто и в общем кое-как работает, но приводит к небольшим потерям производительности то тут, то там. Ну, знаете, мелочь, пофиксить которую руки никак не дойдут. Беда лишь в том, что десяток таких «мелочей», разбросанных в разных местах кода начинают приводить к проблемам типа «вроде у меня последний Intel Core i7, а прокрутка дёргается».

Я говорю о неверном использовании функции Sleep (регистр может отличаться в зависимости от языка программирования и платформы). Итак, что же такое Sleep? Документация отвечает на этот вопрос предельно просто: это пауза в выполнении текущего потока на указанное количество миллисекунд. Нельзя не отметить эстетическую красоту прототипа данной функции:

void Sleep(DWORD dwMilliseconds);

Всего один параметр (предельно понятный), никаких кодов ошибок или исключений — работает всегда. Таких приятных и понятных функций очень мало!

Ещё большим уважением проникаешься к этой функции, когда читаешь, как она работает
Функция идёт к планировщику потоков ОС и говорит ему «мы с моим потоком хотели бы отказаться от выделенного нам ресурса процессорного времени, сейчас и ещё на вот столько-то миллисекунд в будущем. Отдайте бедным!». Слегка удивлённый подобной щедростью планировщик выносит функции благодарность от имени процессора, отдаёт оставшийся кусок времени следующему желающему (а такие всегда найдутся) и не включает вызвавший Sleep поток в претенденты на передачу ему контекста выполнения на указанное количество миллисекунд. Красота!

Что же могло пойти не так? То, что программисты используют эту замечательную функцию не для того, для чего она предназначена.
Читать дальше →

Реализация алгоритма k-means (k-средних) на примере работы с пикселями

Время на прочтение12 мин
Охват и читатели41K
Всем привет! Недавно нужно было написать код для реализации сегментации изображения с помощью метода k – средних (англ. k-means). Ну, первым делом Google в помощь. Нашел много информации, как и с математической точки зрения (всякие там сложные математические каракули, хрен поймёшь, что там написано), так и некоторые программные реализации, которые есть в английском интернете. Эти коды конечно прекрасны – спору нет, но саму суть идеи сложно поймать. Как – то оно там все сложно, запутано, да и пока сам, ручками, не пропишешь код, ничего не поймешь. В этой статье хочу показать простую, не производительную, но, надеюсь, понятную реализацию этого чудесного алгоритма. Ладно, погнали!
Читать дальше →