-
Сообщений
16 850 -
Зарегистрирован
-
Посещение
-
Время онлайн
189д 15ч 29м 28с
Все публикации пользователя Grohuf
-
Давай я напомню основные тезисы: 1) Тестировать многопоточные ошибки сложно. GR: Ахаха, вы просто не умеете писать тесты <далее приводит пример с тестированием имплементации>. 2) Вопрос, можно ли тестировать с помощью слипа. Тут я привожу пример реальной баги, где хуй проссышь, как надо было писать тест, чтобы ее надежно отлавливать. Но зато ее можно воспроизводить слипом. 3) GR несет хуйню по поводу примера, ибо ни разу не видел код, где счетчик ссылок лежит внутри объекта. 4) GR говорит, что такие указатели дерьмище и приводит пример продуманного shared_ptr. 5) GR говорит, что тестом, с миллиардом потоков, теребонькающих подозрительные классы, нельзя найти баг из моего примера. 6) GR говорит, что я не знаком с gmock, хотя знает, что я работаю над Яндекс.Браузером 7) Я сказал, что shared_ptr хуев, ибо делает две аллокации в куче, чтобы избежать которые надо использовать make_shared. 8) GR сказал, что shared_ptr охуенен и надежен, а еще в нем всегда используются атомики, но это хуйня, потому что атомики практически бесплатны 9) GR сказал, что я не прав, что нельзя передавать сырой указатель, пользуясь shared_ptr. Правда забыл упомянуть, что enable_shared_from_this нельзя использовать вместе с make_shared (привет двойная аллокация). 10) GR сказал, что лучше shared_ptr, чем ловить ошибки. И вообще, он пишет на си++, чтобы забивать на производительность, ибо язык и так быстрый. 11) GR приводит ссылку на гугловый кодстайл, который собственно о кодстайле, а не о том, какие библиотеки использовать. 12) GR думает, что суть в том, что гугл тоже юзает атомики, а не в том, что GR говорит, что они бесплатные или в том, что двойная аллокация - это плохо.
-
Уже потерял нить разговора? Бедный.
-
https://chromium.googlesource.com/chromium/src.git/+/refs/heads/main/styleguide/c++/c++-features.md#std_shared_ptr-banned Ты ссылаешься на общий гугловый гайдлайн, который применяется и к утилитам, написанным для мелкой задачи, в которых пилить свой фреймворк глупо.
-
А с чем я должен сравнивать? Для того, чтобы можно было себе что-то позволять, нужно знать какие там накладные расходы. Что тоже выделение памяти в куче как минимум приведет к прокручиванию спинлока, а в худшем случае к переходу в режим ядра. Что непопадание в кэш - это пиздец как плохо и сильно замедляет работу. А чтобы не сидеть и не думать, могу ли я позволить себе вот эти накладные расходы, проще писать всегда правильно, не используя заведомое говно, типа shared_ptr. Именно такая политика в google, касаемая всякого говна из std. У нас тут один коллега делает патч в llvm, потому что реализация перебора файлов в директории на Win в 10 раз медленнее нормальной. Ребята типа тебя написали во внутренней утилите перебор файлов с помощью std::filesystem, не задумываясь о последствиях. Действительно. И так нормально. Ребята, которые писали реализацию для clang тоже, похоже, думали, что и так нормально. Хули тут думать?
-
Я отнаследовался от потокобезопасного класса, включающего подсчет ссылок. Там нет ни слова про указатель в названии класса. Ага. Всего-то вставляет барьер памяти (не давая оптимизировать код), синхронизирует кэши в разных ядрах и не дает обращаться к ячейке памяти другим ядрам. "Почти" бесплатно. Ну если ты программист на си++, а не программист на Java/Python, как всеми уважаемый дуит, у которого все языки работают с одинаковой скоростью, то должно. Два выделения памяти - это лишние 16 байт накладных расходов, захват критической секции, а самое главное - фрагментированность памяти, мешающей кэшированию процессора. Плюс лишняя косвенная адресация. А так да, "Почти" бесплатно. Ты серьезно? Ты простейший код не понял, а там надо смотреть одни сплошные шаблоны.
-
Как он может ничего не стоить, если там нужен атомарный инкремент/декремент? То есть тебя не смущает, что без make_shared он выделяет память в куче дважды? Бля, раньше ты мне казался умнее. То ли ты тупой, то ли ты в своем болоте неплохо так деграднул со своими братишками. Так Goldrobot даже не догнал, что наследование у класса A нужно для добавления функция AddRef и ReleaseRef, чтобы не писать их в каждом классе вручную.
-
Класс A не является умным указателем. Ахаха.
-
Не надо пиздеть. Атомарный инкремент гораздо медленее работает обычного инкремента. То есть ты сельский дурачок, который не понял довольно простой пост. Там написано "Когда он создается, он не выставляет счетчик ссылок в единицу, потому что всегда он присваивается умному указателю, который инкрементирует этот счетчик на единицу." Чего там может быть непонятно - я не представляю. Походу ты совсем тупой. Ого, пробиваешь очередное дно. Все тесты хромиума на нем написаны. Попробуй сделать логический вывод, знаком ли я с тем как они пишутся? "Ту хуйню", которую ты не понял, что значит? Но на всякий случай лучше сжечь? Разумно.
-
Чекнул cppreference. Оказывается при использовании std::make_shared weak_ptr не дает удалиться памяти, занимаемой всем объектом. Ну да, логично, там же одна аллокация. Короче, говно-говном.
-
Моканье времени - вполне обычная практика. Хотя чаще надо мокать тики процессора, так как именно они в нормальном коде используются для пауз и измерения промежутков времени.
-
Чел, я работаю над хромиумом, который делают в гугле. https://chromium.googlesource.com/chromium/src.git Если у тебя сложности с поиском Там все написано. Напряги извилины чуть-чуть. Ты хоть в курсе, как написана библиотека std? Не просто так многие вещи из нее в гугле забанены. Использование std::make_shared является обязательным. Создал объект как-то не так - привет лишние тормоза. Никаких средств быть уверенным, что объект создается именно так. Если тебе неудобно - похуй, изворачивайся. Нельзя передавать сырой указатель, поэтому всегда лишние работы со счетчиком, которые в многопоточной среде должны быть атомарными.
-
Это писал не я, а чел из гугла. Я просто это фиксил (апстримил, офк). Ты еще не знаешь проблем шаредптра...совсем плох. А такие умные указатели (в бусте они называются intrusive) используются далеко не только в Chromium. Например, в свое время в COMе было сделано именно так. Я уже писал выше. Нагрузочное тестирование. Реализовать его мне хватило ума, когда у меня был 1 год стажа работы. В чем у тебя проблемы - не понимаю. Ты про свои гениальные тесты вида: MyClass::MyFunc() { member_variable_ = 1; } MyTest() { MyClass tested_class; tested_class.MyFunc(); assert(tested_class.member_variable_ == 1); } ? Да, очень полезные тесты. Согласен. Пишешь код в классе, а потом пишешь в тесте проверку, что все операции в функции действительно выполнились. Я просто опустил шаблонную магию, чтобы было легче читать. Так-то понятно, что будет создан шаблоном код, который вызывает this->AddRef(). Я вроде все расписал, а ты все равно не понял.
-
Есть много причин, почему нельзя писать сложный код в конструкторе и вместо этого использовать методы Init(). Хотелось бы настучать Страуструпу по ебалу за гениально спроектированный язык.
-
Ты не знаешь, где надо поставить слип, пока не видишь баг/крэш. Пример хитровыебанного бага: Class A : ThreadSafeRefcounted<A> { // тут что-то }; A::A() { PostTaskOnWorkerThread(this, &A::SomeMethod); } main() { auto a = MakeRefCounted<A>(); } Класс A - с подсчетом ссылок. Когда он создается, он не выставляет счетчик ссылок в единицу, потому что всегда он присваивается умному указателю, который инкрементирует этот счетчик на единицу. Однако в данном случае PostTaskOnWorkerThread тоже будет инкрементировать счетчик на единицу, чтобы объект жил, пока выполняется таска на другом треде. Когда таска выполнится - счетчик уменьшится. Так вот, если задача выполнится до окончания конструктора (что маловероятно, но может быть), то PostTaskOnWorkerThread уменьшит счетчик на единицу, счетчик станет равным нулю и объект удалится на другом потоке (несмотря на то, что конструктор еще не закончился). Когда умный указатель будет инкрементировать счетчик, он это будет делать у мертвого объекта (крэша скорее всего не будет в этом месте, но будет потом). Чтобы воспроизвести этот крэш, надо поставить слип после PostTaskOnWorkerThread. Наитупейший и бесполезнейший вариант тестов, которые у нас бывают пишут на "отъебись", чтобы не спрашивали "а почему нет тестов?"
-
Слипом подтверждается наличие бага. То есть, у тебя где-то стреляет изредка, ты предполагаешь многопоточный баг. Находишь предполагаемое место, чтобы его имитировать, вставляешь в нужном месте слип. У тебя получается 100% воспроизведение. Значит баг найден правильно. Потом можно, конечно, на этот случай накалякать тест, который будет дергать функции в нужном порядке, но он будет тестировать только этот баг, плюс часто для этого придется раскурочивать тестируемый класс, так что мб имеет смысл и забить.
-
По факту уже все сказано. Если ты не понял его доводы, то чем я могу помочь? У каждого есть свой предел. Многопоточные ошибки плохо тестируются. Более-менее надежный способ предполагает длительное нагрузочное тестирование, которое занимает время и поэтому плохо подходит для тестирования на каждый пулл-реквест. Многопоточные ошибки легко совершаются, трудно находятся и плохо тестируются. Поэтому код в 99% случаев надо писать без локов, а весь потокобезопасный код должен быть в базовых библиотеках, которые хорошо протестированы.
-
Ну хоть в многопоточности дуит разбирается. А в золотом роботе я разочаровался. Похоже, его оклад соответствует навыкам.
-
Тебе дуит правильно сказал, что хуй ты проверишь, что в данной реализации компилятор решил переставить присваивание переменным значений и что нужно было вставить memory barrier. У меня был другой случай. Код крэшился надежно только на определенной ОС. Причина? На данной ОС при захвате мьютекса гарантировано происходило переключение потоков. В то время как на других ОС переключение потоков происходило более ожидаемым образом (по времени и приоритетам) и воспроизвести проблему было нереально.
-
Это правда пишет наш немецкий разработчик?
-
Вообще, при хороших базовых библиотеках методы у нетредсейф класса могут вызываться с разным потоков, но это не создает проблем. Но вся эта механика спрятана, как выше написал мистер трололо, и ты об этом не думаешь.
-
Лучше Surge первый пройди
-
Это не обязательно, если используется асинхронщина. Но тогда нужно ставить ассерты, если класс дернули не с того потока.
-
В нормальной инфраструктуре про многопоточность особо не думаешь. Должна быть удобная система из пула потоков и постановки задач в него. Если она есть, то весь код представляет из себя перекидывание задачами из одного таск раннера в другой. Примитивы синхронизации при этом не используются.
-
да я сам уже 2 года 100+ вешу, хотя раньше очень легко и долго на 90 держался с таким же ростом как и у тебя. Мне вот чё интересно стало, я вспомнил что у меня раньше на ногтях в детстве появлялись такие типа белые пятнышки, и они не пропадали пока не сострижёшь эту часть, что это было? сейчас у меня такого нет. Тут нужен спец по грязным ногтям @mamont27reg