Бестиарий программирования
1.14K subscribers
403 photos
5 videos
6 files
498 links
Наблюдения за жизнью ошибок в коде.
Андрей Карпов.

ГОСТ Р 71207-2024, ГОСТ Р 56939-2024, РБПО, Статический анализ кода

Канал-дублёр в MAX: https://max.ru/join/3VWTp9apkQvTMSRQ__LGiTQ5NGVBj8p_tOpwlQO6vS8
Download Telegram
Короче и быстрей (часть №3 из 5) – Объединяем циклы - Заглянем в ассемблерный код

Текст функции стал короче, но скажется ли это положительно на производительности? Да. Посмотрим на основной фрагмент ассемблерного кода для изначального варианта функции. Используется Clang с ключом -O2.
.LBB1_7:
mov rax, rsi
mov qword ptr [rbx + 8*r12 - 16], rsi
mov rsi, qword ptr [r13 + 8*r12 - 16]
cmp rsi, 1
adc rsi, 0
imul rsi, rax
dec r12
cmp r12, 1
ja .LBB1_7
mov r12d, 1
cmp rbp, r13
je .LBB1_9
.LBB1_4:
mov rax, qword ptr [r13]
test rax, rax
je .LBB1_5
imul r12, rax
add r13, 8
cmp r13, rbp
jne .LBB1_4
jmp .LBB1_9

Достаточно многословный ассемблерный код с двумя циклами. Теперь посмотрим, что сгенерировано для последнего сокращённого кода.
.LBB1_10:
mov rcx, rsi
mov rdx, qword ptr [rbp - 8]
add rbp, -8
mov qword ptr [rax], rsi
cmp rdx, 1
mov rsi, rdx
adc rsi, 0
imul rsi, rcx
imul r12, rdx
add rax, -8
cmp rbp, r13
jne .LBB1_10

Красивое. Один цикл. Коротко и быстро.
⚡2👍2
Короче и быстрей (часть №4 из 5) – Альтернативный подход

Есть какой-то другой альтернативный подход? Есть. Не знаю, догадался ли я до него сам или нет. К сожалению, после написанию своего варианта кода, я поспешил поспрашивать, какие варианты могут предложить ИИ.

Варианты от DeepSeek были не лучше, а некоторые даже хуже исходного. Например, он сократил одну из реализаций кода ценой переворачивания массива.
// Разворачиваем strides обратно
std::reverse(strides.begin(), strides.end());

А вот одна из альтернативных реализаций от Claude Opus заслуживает внимания. Он обратил внимание, что можно выполнять не две, а одну последовательность умножений!

Если все элементы входного массива не нулевые, то по завершению цикла acc == ne. А если хотя бы один элемент был нулевой, то в конце можно просто поменять значение ne на ноль. Происходит вновь возвращение к флагу any_zero, но в более умном варианте. Используя эту идею, можно написать следующий код:
static TensorImpl make_contiguous_tensor(const std::vector<int64_t>& sizes) {
  auto q = sizes.size();
  std::vector<int64_t> strides(q);
  int64_t acc = 1;
  bool any_zero = false;
  for (auto sz : std::ranges::views::reverse(sizes)) {
    strides[--q] = acc;
    acc *= (sz == 0 ? 1 : sz);
    any_zero |= sz == 0;
  }
  const int64_t ne = any_zero ? 0 : acc;
  ....
}

Ассемблерный код:
.LBB1_7:
mov rdx, rsi
mov rsi, qword ptr [r13 - 8]
add r13, -8
mov qword ptr [rcx], rdx
test rsi, rsi
sete dil
cmp rsi, 1
adc rsi, 0
imul rsi, rdx
or al, dil
add rcx, -8
cmp r13, rbp
jne .LBB1_7
xor r13d, r13d
test al, 1
cmove r13, rsi
mov r14, r8

Будет ли код, в котором выполняется в два раза меньше умножений, более быстрым? Моё предсказание – необязательно. Процессор может выполнить два невзаимосвязанных умножения одновременно на разных конвейерах. Я делаю ставку, что мой вариант и вариант от Claude будут работать с практически одинаковой скоростью.
⚡1👍1
Короче и быстрей (часть №5 из 5) – Замер скорости работы и заключение

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

Не утверждаю, что измерения выверены, но общее представление они дают. Скорость работы первого изначального алгоритма взята за единицу отсчёта. Использовал Clang с ключом -O2.

1.      Изначальный вариант c двумя циклами: 1.
2.      Мой вариант одним циклом: 0.88.
3.      Вариант, подсказанный Claude, с одним умножением: 0.92.

Рефакторинг дал ускорение в среднем на 10 %. Я ждал, что будет побольше, в районе 20—30 %. Но 10 % — это тоже хорошо, учитывая, что они достигнуты упрощением, а не усложнением кода.

Заключение

На этом разбор кода и его рефакторинг закончен. Был ли в этом смысл?

С точки зрения улучшения конкретно этого кода – нет. Это сгенерированные тесты. Некритично, что код длиннее и медленнее, чем он может быть.

С образовательной точки зрения – да. Неважно, создаётся код человеком или генерируется с помощью ИИ. Нужны эксперты, которые могут отличить хороший код от плохого. Быстрый он или нет. Безопасный он или нет.

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

ИИ — это мощный инструмент, но не волшебная палочка. Когда Claude подсказал мне альтернативный вариант алгоритма, это хороший пример, что ИИ можно использовать для исследований и усиления возможностей человека. Но точно также он легко нанесёт вред при бездумном использовании.

P.S. Кстати, про волшебную палочку подметил кое-что интересное, завтра напишу.
👍5❤1
ИИ-кладенец

Вспомнилась мне давеча книга "Исторические корни волшебной сказки" Владимира Яковлевича Проппа. Это монументальное исследование сказок: как они зарождались, трансформировались, что в них означают разные сущности и т. д. Не берусь рекомендовать, так как литература специфичная, и я с ней знакомился из желания размять мозг непривычным.

Вспомнилась она мне из-за воодушевления авторов статей, что вот ещё чуть-чуть и ИИ всё сделает за нас и "скрипач не нужен" (c). Я вдруг увидел связь между "ИИ сделает сам" и темой волшебных предметов и помощников, которую подробно разбирает Пропп.
Рассмотрение волшебного помощника облегчает и подготовляет рассмотрение волшебного предмета. Между ними существует теснейшее родство. Легко заметить, что эти предметы представляют собой лишь частный случай помощника. Помощники, живые существа и волшебные предметы, принципиально функционируют совершенно одинаково. Так, конь переносит героя за тридевять земель, но то же достигается при помощи ковра-самолета или сапог-самоходов. Конь побивает рать, но и дубина сама бьет врагов и даже берет их в плен и т. д.

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

Думаю, вы поняли, к чему я клоню. Сейчас всё теми же волшебными свойствами наделяют ИИ-технологии и ожидают от них чудесного решения проблем без усилий. Это — новый волшебный помощник.

Вроде все понимают, что ИИ — это инструмент, которым надо уметь пользоваться: что есть сложности и проблемы; что он помогает, но не заменят труд. По-серьёзному никто не говорит, что ИИ — это магия, но почему-то многие продолжают преподносить ИИ или воспринимать его как дубину, которая сама бьет врагов. Хотя для этого на практике нужна крепкая рука и физическая работа. Но нет, подавай "трах-тибидох".
Человек в меньшей степени замечает свое усилие и в большей — работу орудия. Так получается концепция, что орудие работает не в силу прилагаемых усилий (чем совершеннее орудие, тем меньше усилия), а в силу присущих ему волшебных свойств. Получается представление об орудии, работающем без человека, за человека. Орудие теперь обожествляется.

Вывода нет. Подметил интересное проявление мало осознаваемых психологических паттернов использования новых технологий/орудий труда. Сейчас, конечно, знания создаются на порядок быстрее, и разум более гибок и быстрее переучивается, но всё же какое-то прежнее, древнее восприятие мира влияет на нас, просвечивая сквозь слой образования и культуры.
🔥5👏5
Пометка в блокноте – Не забывать писать, сколько лет PVS-Studio на рынке

Услышал на Бизнес-Фест в докладе Игоря Манна мысль, что не стоит забывать упоминать в разных местах, как давно вы на рынке. Это автоматически добавляет пару очков доверия. И действительно! "PVS-Studio — более 18 лет на рынке РФ" звучит солидно!

В числах:

Компания ООО "ПВС" (ранее "СиПроВер", переименована в "ПВС" в 2020 году) зарегистрирована 21 марта 2008 года. В этом году отметили совершеннолетие – 18 лет!

Нашему продукту, который изначально назывался Viva64, тоже более 18 лет. Уже под названием PVS-Studio он был зарегистрирован 30 октября 2009 года.

P.S. Кто угадал отсылку на картинке? Великий герой — Коэн-варвар из книг о Плоском Мире.
❤5
PVS-Studio теперь в GitVerse🔥

Мы добавили готовые шаблоны для статического анализа в GitVerse Starter Workflow (российский аналог GitHub/GitLab от «СберТеха»).

Что это дает?
Больше не нужно писать пайплайны с нуля. Теперь внедрить автоматическую проверку кода в CI/CD можно за пару минут.

Как это работает:
- При настройке workflow в GitVerse выбираете шаблон PVS-Studio под свой язык: C++, C# или Java.
- В шаблоне уже прописаны базовые этапы сборки и анализа.
- Слегка адаптируете настройки под свой проект — и готово!

"Каждый шаблон уже включает основные этапы сборки и статического анализа. После небольшой адаптации под особенности конкретного проекта пайплайн готов к использованию и может быть встроен в процесс CI/CD", — отмечает Валерий Филатов, Developer Advocate PVS-Studio.


Отличный способ сэкономить время на настройке инфраструктуры и повысить надежность кода 👍

Для пользователей GitVerse сделали специальный промокод. Пользуйтесь PVS-Studio 30 дней без ограничений: https://pvs-studio.ru/gitverse

#PVS_Studio #GitVerse
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Запись вебинара "Практическая интеграция PVS-Studio и SourceCraft" 🔥

В том числе будет про то, как ИИ помогает работать с предупреждениями анализатора. Получилась интересно, рекомендую познакомится с записью.

Посмотреть можно тут:
- VK Video
- Rutube
- YouTube
- Наш сайт
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Я сижу со взглядом на две тысячи ярдов после прочтения статьи "Манифест программиста, использующего AI-кодинг-агента". Как говорится, то ли смеяться, то ли плакать. Ну на смех в паре мест меня пробило.

К самой статье претензий нет: я потрясён тем, что вообще у кого-то возникла потребность в написании этого манифеста. Как быстро где-то в индустрии уровень разработки прошёл путь от обсуждения книг про написание качественного кода до режима "голова для того, чтобы туда кушать".

Я пока сомневаюсь, что настолько всё плохо. Надеюсь, автор преувеличивает и иронизирует. А если нет? О, мой Дейкстра!
Появился тикет. Программист копирует ссылку, передает ее AI-кодинг-агенту и через какое-то время получает готовый Pull Request.
...
Перед изменением кода программист должен воспроизвести баг, понять условия его появления и увидеть фактический результат.

Скажите, что я сплю. Если вайб-программист просто впихивает задачу, не воспроизводя баг, не разбираясь в сути и не проверяя результат правок... это вообще что?
Если программист не запустил продукт и не проверил результат, задача не закончена. Если программист просто передал тикет AI, а потом передал его код ревьюеру и тестировщику, он не выполнил свою работу. Он просто переложил ее на следующих людей.

База. Но ведь автор это всё написал зачем-то, а в комментариях всерьёз идёт обсуждение. Прошу прочитать эту статью, она небольшая. Интересно услышать ваши впечатления, мнения и комментарии. Хочется вынести из всего этого происходящего сюрреализма какие-то полезные выводы.
👍9😁1
Forwarded from СВД ВС
Современная разработка начинается с правильных инструментов.

Завершился курс «Инструментальные средства ЗОСРВ «Нейтрино».

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

Это позволило участникам познакомиться с современными подходами к повышению качества и надёжности программного обеспечения.

Все участники успешно прошли тестирование и получили удостоверения о повышении квалификации.

Обучение продолжается. Следите за анонсами новых наборов и выбирайте курс, который поможет решить ваши профессиональные задачи.

#Курсы
👍4❤1
Кажется я превратился в тролля. Но автор заслужил :)

Мой комментарий к статье "Операционная Система на C без знаний C".

Я так понимаю, речь идёт об этом проекте OS. Мдя. Ну что же, автору предстоит узнать ещё много о языке С. Например, что такое выход за границу буфера.
void terminal_write_hex(uint64_t hex_num) {
    uint64_t index_buffer = 0;
    char buffer[sizeof(uint64_t)];
    if (hex_num == 0x0) {
        terminal_write("0x0");
        return;
    }
    terminal_write("0x");
    while (hex_num > 0) {
        uint64_t digit = hex_num % 16;
        if (digit >= 10) {
            digit = digit - 10;
            buffer[index_buffer] = 'A'+digit;
        }else {
            buffer[index_buffer] = '0' + digit;
        }
        hex_num = hex_num / 16;
        index_buffer++;
    }

Какой милый баг. Посмотрите на размер буфера: не учитывается, что один байт превращается в два символа. Интересные времена "безопасного ПО" настают. Простите за едкость комментария, но не удержался, увидев проект автора:
Safe Life System

Наш проект — это платформа для обеспечения и сохранения безопасности информации в цифровой среде, а также для развития независимой IT-экосистемы.

Мы создаём комплекс программного обеспечения, ориентированный на защиту данных, открытость технологий и поддержку русскоязычного IT-сообщества.
🤣9🔥3
kstrncmp
uint64_t kstrncmp(char *str1, char *str2, uint64_t len){
uint64_t index_str = 0;
uint64_t different_char = 0;
while (index_str < len) {
if (str1[index_str] != str2[index_str]) {
different_char++;
}
index_str++;
}
return different_char;
}
😭5👨‍💻1
Хорошая новость для разработчиков на Unreal Engine: мы сделали PVS-Studio доступнее, и теперь анализ UE-проектов в PVS-Studio доступен в лицензии Team, а не только в Enterprise. Подробности.

Если вы работаете с Unreal Engine и давно присматривались к PVS-Studio, то сейчас самое время попробовать анализатор на своём проекте. А если возникнут вопросы по интеграции или настройке, наша команда поддержки всегда поможет вам разобраться.
👍3
Ошибка, которую никто никогда не совершал. Ведь так, да?
Уже с первого курса университета — или даже раньше — вы могли догадаться, что писать arr[len(arr)] — плохая затея. И вряд ли так кто-то может ошибиться, правда? Мы тоже так думали, пока не проверили 1000 проектов.


Прогрев Go анализатора :)
🤓4🔥3
Статический анализатор — мощный, но не всегда простой инструмент.

Поэтому мы подготовили для вас курс "Статический анализатор PVS-Studio на практике"!

Что вас ждет:
- Вы узнаете возможности анализатора, актуальные требования ГОСТ и как устроено лицензирование PVS-Studio.
- Познакомитесь с локальной работой с PVS-Studio в плагине для IDE.
- Поймёте, как встроить PVS-Studio в рабочий процесс разработки и минимизировать ручную работу.
- Узнаете про использование PVS-Studio в роли SAST-инструмента для автоматического поиска ошибок и потенциальных уязвимостей в исходном коде.
- Разберётесь с системой мониторинга компиляции и разметкой предупреждений по стандартам MISRA на практике.

Подробнее о курсе по этой ссылке 🔗

P.s. курс абсолютно бесплатный 😉
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7
В этот чудесный летний день мы предлагаем вам сделать коллаборацию! 🔥

А какие варианты взаимодействия есть и куда писать — можно узнать по ссылке 🔗

#PVS_Studio #статья
Please open Telegram to view this post
VIEW IN TELEGRAM
Кто сразу видит ошибку в реализации паттерна double-checked locking в Java коде? :)
public class KubernetesDevUIProcessor {
static volatile List<Manifest> manifests;
public List<Manifest> getManifests() throws BootstrapException {
if (manifests == null) {
synchronized (Holder.class) {
if (manifests == null) {
manifests = new ArrayList<>();
....
try (CuratedApplication bootstrap = quarkusBootstrap.bootstrap()) {
....
for (var entry : context.entrySet()) {
manifests.add(
new Manifest(entry.getKey(),
new String(entry.getValue()))
);
}
}
}
}
}
return manifests;
}
}

Заглядывайте в публикацию, мы и других багов принесли - Проверяем Quarkus 🔥
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Когда ИИ платят за строки кода :)
static int ksys_read(int fd, char *buf, u32 len) {
u32 i;
char c;
int pid = (int)ring3_current_pid;
int slot;

if (fd != 0 || !buf) {
if (fd != 0 || !buf) {
if (fd == 0) {
return ERR_FAULT;
}
}
}
....
}


Проверка эквивалентна
if (!buf && fd == 0)
return ERR_FAULT;

и выглядит подозрительно. Но мне сейчас лень изучать код дальше. Просто поделился тем, что улыбнуло :)
😁12