Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>То есть ты заменил одну структуру данных, на совершенно другую, с другой алгоритмической сложностью и с другими требованиями к типу данных, и на основе этих опытов пришёл к выводу что std::map тормозит?
Этож не я говорил, что тормозит. Я подтвердил, что "с остальными контейнерами не всё так гладко". Ну я еще unordered_map замерял. А так да, действительно совсем другая структура и требования к данным. Их не корректно сравнивать с этой точки зрения.
Здравствуйте, greenpci, Вы писали:
EP>>std::map на что заменили? На дерево со встроенным free-list? G>Сам полностью написал хэш мэп. Под наши специфические данные нужно было память экономить.
И как он по памяти и скорости выигрывает у std'шного hashmap? Неужели так заметно?
Здравствуйте, Nuzhny, Вы писали:
N>И как он по памяти и скорости выигрывает у std'шного hashmap? Неужели так заметно?
Да. При большом количестве итераций. Сейчас цифр не помню, да и бесполезны они здесь, так как наших данных и контекста все равно ни у кого не будет. А с коллегами я это все обсудил.
Здравствуйте, greenpci, Вы писали:
G>Да. При большом количестве итераций. Сейчас цифр не помню, да и бесполезны они здесь, так как наших данных и контекста все равно ни у кого не будет. А с коллегами я это все обсудил.
Проясню ситуацию. Тот хэш мап, что я сделал, не подойдет как замена СТЛьному, так как он был неразрывно связан с нашими данными. Как уже верно заметили выше, его не корректно сравнивать, так как он не заменит СТЛьный хэш мап.
Здравствуйте, Cyberax, Вы писали:
V>>Так это же отлично. V>>Но ты не объяснил мне, зачем вручную заставлять делать точно так же, если компилятор генерит такой же код при копировании вектора? C>Быстрее.
Нет.
Т.е. совсем совсем нет.
Тот код, что ты показал — работает заведомо медленнее.
V>>К тому же, MSVC вызывает библиотеку только для случая, когда количество копируемых байт на этапе компиляции неизвестно, а это достаточно редкий сценарий, который к тому же говорит, что в консерваитории что-то не так. )) C>memcpy из glibc работает быстрее нативного копирования во всех случаях, когда размер не известен статически и больше порядка 64 байт.
Опять нет. ))
Вот не везет тебе.
Для вектора генерится код, копирующий данные блоками по 128 байт. Самое важное отличие от кода по твоим ссылкам я опишу чуть ниже (т.к. там один и тот же принцип, что для достаточно больших размеров даже известных данных, что для общего случая — практически идентичный код генерится).
И ты не ответил на самое важное:
Голые байты на тех сценариях, в которых важно быстродействие memcpy, "перекачивают" блоками фиксированного размера. Это важно и это, действительно, даёт заметный профит
Т.е. за счет косметических модификаций процесса обработки данных можно снизить затраты на "голые копирования" в 3-5 раз.
Это если, действительно, выделенное имеет значение в тех алгоритмах.
Но то, что ты описал:
Сейчас единственное улучшение в нашей внутренней STL — это специализация векторов для POD-объектов, которые можно сразу через memcpy копировать.
Это непонимание основы основ в плане "перекачки" данных и вообще — как надо писать матан или эффективный сетевой диспатчинг.
И я объяснял — почему:
Да еще ты дал код для копирования через memcpy невыровненных даных...
Какая боль... в обсуждении про то, как важен быстрый memcpy.
Жесть ))
V>>Разве у других сломался вывод в дизассемблированном виде при отладке? C>Ну так покажи что там генерирует MSVC. Мы посмеёмся вместе.
Я же тебе сказал уже:
Раз:
При копировании STL вектора для POD-типов в релизе он тоже перекачивает память через MMX/SSE/AVX точно так же, как в тех случаях, когда используются массивы заведомо известного размера.
С тем важным отличием, что нет 4-х лишних ветвлений, начинающихся в коде от метки L31 и еще 4-х ветвлений в L(less_16). Ты изучи те отрезки повнимательнее. Поймешь, чем именно ты вызвал столько улыбок. ))
И да. Я оч много писал на асме в своё время. Читай в другой раз код, который мне кидаешь, чтобы не было как в этот раз.
Нормальный компилятор на этапе компиляции ЗАВЕДОМО знает кратность размера данных, поэтому НЕ ГЕНЕРИТ лишних ветвлений и процессор по ним не гуляет. А что такое лишнее ветвление в "критичном memcpy"? Да это приговор, собсно.
Далее, он точно так же выполняет "раскрутку" цикла, т.е. тело цикла за раз перекидывает 128 байт (как по твоей ссылке в основном теле алгоритма), но нет кучи сравнений и переходов для копирования всевозможных "хвостиков-остатков" данных, т.к. размер, либо кратность данных (в случае STL-вектора) заведомо известны:
В коде sizeof(S1) == 288. Специально взял некратную величину для демонстрации того, что происходит, когда кратность данных заведомо известна (а она в ТВОЁМ случае таки была заведомо известна).
Если на вашей платформе MSVC недоступен — откройте для себя Intel Compiler. Тоже офигенно управляется с интристиками. Всячески рекомендую.
Ну и, модифицировав алгоритм таким образом, чтобы на каждом этапе обрабатывались данные фиксированного размера (пакеты), вместо всего того мусора по твоей ссылке, и даже вместо приведенного куска с одним ветвлением и счетчиком "оборотов" в r8, будет просто 4 пересылки, если взять буфер в 128 байт или построить на "шаблонной раскрутке" кратный по размерам буфер. Т.е. будет вообще БЕЗ ВЕТВЛЕНИЙ. Именно на прокапсенном затраты на конкретно операции копирование падают в 3-5 раз (в зависимости от размера "пакета".. например, если речь идет о десятках килобайт простого копирования за раз, то тут уже что-то не то и на матан или кодеки это не тянет и там уже многое будет пофиг, бо с таким загрязнением кеша данных сильнее всего будет тормозить уже кеш, чем что бы то ни было).
Те же самые рассуждения верны для ситуации, когда данные не просто копируются, а обрабатываются каким-нить матаном в процессе перекачки из буфера в буфер (для относительно небольших буферов, ес-но, на которых только все эти оптимизации и имеют смысл).
V>>И почему для разных процессоров, если у меня проц подерживает одновременно SSE2, AVX и AVX D? C>А у меня не поддерживает AVX. А на другом процессоре SSSE3 быстрее. Что мне делать?
SSE3 быстрее в копировании... Это уже предел падения, коллега. Курить отличие SSE3 от SSE2.
Как домашнее задание — попытаться найти в SSE3 хоть инструкцию, которая может загружать в регистры более "широкие" данные или выгружать более широкие.
Еще домашнее задание — попытаться найти проц БЕЗ поддержки SSE2 на x64 — архитектуре (AMD64 которая).
Как говорят украинские политики, "ты уже на 15 лет наговорил". Натурально. ))
V>>От тебя всегда как привет из параллельной реальности )) C>То что ты ничерта не знаешь, не хочешь знать, и являешься эталоном полного ламера — мы уже давно выяснили.
Хосподя, конкретно ты далеко не всегда понимаешь о чем даже речь.
Это из-за лени, ИМХО, потому что никакой "закрытой" инфы я не даю, всё всегда можно проверить самому. Было бы желание.
Вдогонку.
Обратил внимание, что по одной из ссылок (для SSE3) есть еще дополнительная возня и дополнительные ветвления в попытках применить MOVAPS вместо MOVUPS.
Всем валяться!!! )))
В процессорах с 2008-го года скорость MOVAPS и MOVUPS идентичная для выровненных по границе 16 байт данных.
А для твоего случая, если вы там не намудрили со своими аллокаторами, в x64-режиме под STL-вектор (твой случай) ВСЕГДА будут выделяться данные, выровненные на границе 16 байт.
Здравствуйте, watchyourinfo, Вы писали:
W>Компилятор с такой опцией включенной не удовлетворяет стандарту.
Не знал. Я думал, это дизайн такой упоротый. Ну ладно, ОК, проблемы начинаются где-то после стандартизации. Когда создатели всех промышленных компиляторов добавляют такую фичу. И знаете, если подумать еще, это, наверное, все-таки проблема языка — насильно включенный RTTI идет вразрез с изначальными ценностями, неудивительно, что потом его дают отключать.
Здравствуйте, greenpci, Вы писали:
G>Мне кажется, это негативная сторона, так же, как и Google Driven Development. Находя метод в интеллисенсе, программисты переоценивают свое понимание того, что и как он делает. Страшно подумать, сколько раз программисты очищали память с помощью std::ostringstream::clear(). Множество моих знакомых говорили, что они уже не читают книги по программированию, так как в интеллисенсе и гугле все есть. Мне кажется, даже хороший дотнет программист должен знать не только инструкцию к методу фреймворка, но и, иногда, смотреть на его код. Си плюс плюс, как язык "тонкой настройки", тем более требует знания деталей глубже, чем интеллисенс. И я лично за то, чтобы специалисты читали книжки, прежде чем, что-либо делать. Хотя, это и не популярная точка зрения. А новые платформы, как дотнет, настолько быстро меняются, что людям не когда что-то изучать, и это еще одна причина, по которой интеллисенс там так нужен. Создали проблему, решили проблему.
Благодаря гуглу (+ стековерфлоу) это, как раз, у буста (как вынесенных кишок сиплюсплюсных строк) пока еще есть какие-то шансы. ОК, гугл, std string make lower case, понятно, boost::algo, код написан. С FCL же можно работать и автономно, благодаря интеллисенсу и общей эрудиции.
Разбираться затем бывает нужно (или не нужно) и с тем, и с тем, но начинается у нормальных людей все так, как описано выше.
Хуже всего то, что язык форматирует мышление, в результате бОльшая часть архитекторов, которых я видел, предпочитает дикий процедурный подход, не затрудняя себя классификацией более тонкой, чем неймспейсы. Я могу понять, когда это (под?)сознательная защита от новичков на проекте, стремление сохранить рабочее место, но когда это по образцу стандартной библиотеки сделано...
G>Это я еще не упомянул научную книгу "Антимозг", исходя из которой, можно сделать вывод, что интеллисенс также "разрушает" гиппокамус и ухудшает память. G>Но это только моя точка зрения. Большинство все равно его используют и пара лишних, для кого-то ненужных методов будет слегка вредна.
Начал читать, выглядит очень толково. Поэтому ваш вывод меня удивляет сверх всякой меры. Интеллисенс ЗАСТАВЛЯЕТ вас думать и принимать решение, но дает набор сведений, которые можно уподобить дорожным указателям. Их полное отсутствие (как в C++) это экстремальная езда по улицам, лишенным указателей, и возможная только при заучивании наизусть карты города. Мозг от этого упражнения лучше не становится, как и езда безопаснее. Аналогия с GPS из книжки неполная, ибо в программировании просто нет такого, чтобы какая-то программа тебе диктовала, а ты рулил, как крыса в лабиринте. Отсюда мой вывод: книжка эта тут не при чем, а если при чем, то процитируйте явно кусок, который можно применить к интеллисенсу.
BDA>>Как раз вынесение алгоритмов за пределы классов принципиально и не дает воспользоваться этим преимуществом ООП. Процедурщина и хендловщина в полный рост.
G>Ты, прямо, анти-сатер и анти-александреску и еще много людей, как Steve Yegge (да, для меня существую авторитеты)
Хорошо, но тогда общаться с вами настолько же полезно, насколько с любыми другими фанатиками. То есть, бесполезно. Простой пример:
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Нет, далеко не все. Например он не покажет что этот объект может быть аргументом у метода другого объекта
Потому, что это информация не об объекте.
EP>это скорее вопрос к IDE — пусть делают новые формы дополнения, а не только "через точку"
Это принципиально невозможно.
BDA>>Альтернатива — курить маны. То есть, вышел новый стандарт, новый STL, новый boost и вы должны сразу прочитать, понять и запомнить все, что написано в сопроводиловке. EP>Читать документацию придётся в любом случае, чтобы знать контракты.
В хорошем коде контракты выражены через него же. Но даже если нет, индекс контрактов нужен как отдельный инструмент всегда.
EP>А это вообще ортогонально. Декомпозицию на контейнеры и алгоритмы можно делать и в что называется в "true OO style". То есть смотришь ты "с высоты птичьего полета" на класс UTF-8 строки, и видишь что она реализует IBidirectionalSequence, далее смотришь на алгоритмы которые принимают IBidirectionalSequence — и находишь там to_lower, split или что там нужно.
Когда вы покажете, что в IDE можно сделать интеллисенс, не основанный на инкапсуляции, я соглашусь. Но выше я утверждаю, что это невозможно. Однако бремя доказательства обратного я возлагаю на вас — ведь это вы написали «пусть делают новые формы дополнения», вам и показывать, КАК ИМЕННО.
EP>Или ты против такой декомпозиции вообще? Тогда например для каждой строки (и контейнера в общем) придётся придётся реализовывать каждый алгоритм — M контейнеров * N алгоритмов
Зачем? Если алгоритму не важен тип контейнера, он может быть реализован в классе АбстрактныйКонтейнер, а затем переопределен в более специфическом классе. Никакого комбинаторного взрыва.
BDA>>Как раз вынесение алгоритмов за пределы классов принципиально и не дает воспользоваться этим преимуществом ООП. Процедурщина и хендловщина в полный рост.
EP>Ты так говоришь как будто "true OOP" это всегда хорошо, а "процедурщина" плохо.
С меня будет достаточно, если вы подтвердите, что стандартная библиотека C++ — не true OOP. Хорошо это или плохо, мы поговорим в другой раз.
G>std::string ::ToLower() это еще одно выделение памяти и копирование или move (который появился относительно недавно).
Хотел бы я знать, как ты собираешься делать ToLower или ToUpper без перевыделения памяти. Учитывая, что ascii давно на помоечке, а в юникоде эта операция запросто может привести к увеличению фактической длины строки в байтах — и как ее затокать назад в исходный буфер?
Новости очень смешные. Зря вы не смотрите. Как будто за наркоманами подсматриваешь. Только тетка с погодой в завязке.
There is no such thing as a winnable war.
Здравствуйте, Eugeny__, Вы писали:
G>>std::string ::ToLower() это еще одно выделение памяти и копирование или move (который появился относительно недавно).
E__>Хотел бы я знать, как ты собираешься делать ToLower или ToUpper без перевыделения памяти. Учитывая, что ascii давно на помоечке, а в юникоде эта операция запросто может привести к увеличению фактической длины строки в байтах — и как ее затокать назад в исходный буфер?
Во первых, я сказал "еще одно".
std::string ::ToLower()
{
...
return buffer; // вот оно то, которое можно избежать
}
Во вторых, смотри char16_t и char32_t, которые были добавлены в С++11 с целью обеспечить фиксированную длину символа.
Здравствуйте, greenpci, Вы писали:
G>>>std::string ::ToLower() это еще одно выделение памяти и копирование или move (который появился относительно недавно). E__>>Хотел бы я знать, как ты собираешься делать ToLower или ToUpper без перевыделения памяти. Учитывая, что ascii давно на помоечке, а в юникоде эта операция запросто может привести к увеличению фактической длины строки в байтах — и как ее затокать назад в исходный буфер? G>Во вторых, смотри char16_t и char32_t, которые были добавлены в С++11 с целью обеспечить фиксированную длину символа.
В некоторых языках есть некоторые извраты. Например для немецкого: ToUpper ("ß") == "SS".
Здравствуйте, 0BD11A0D, Вы писали:
BDA>Когда вы покажете, что в IDE можно сделать интеллисенс, не основанный на инкапсуляции, я соглашусь. Но выше я утверждаю, что это невозможно.
Т.е. основная причина для толстых классов — чтобы говнопрограммисты через "ctrl-tab" могли код дополнять? LOL.
Талант у человека — что ни напишет, все не в тему. Взять IDE от Java вместо CLion, притянуть поиск по именам в статических методах вместо ПОДБОРА ВСЕХ ПОДДЕРЖИВАЕМЫХ АЛГОРИТМОВ ПО ОБЪЕКТУ, а потом ололокать — это не говнопрограммистом надо быть, а я не знаю, кем.
К сведению тех, у кого смех без причины: если что-то не может делать интеллисенс, это означает, что операция — в данном случае, составление списка всех подходящих алгоритмов — является неавтоматизируемой. Интеллисенс просто служит маркером. И хотя по сути своей, это не творческая, а рутинная задача, она никак не автоматизируется, пока не прибегнешь к инкапсуляции. В том числе поэтому FCL такой, какой он есть.
Здравствуйте, McQwerty, Вы писали:
G>>Во вторых, смотри char16_t и char32_t, которые были добавлены в С++11 с целью обеспечить фиксированную длину символа. MQ>В некоторых языках есть некоторые извраты. Например для немецкого: ToUpper ("ß") == "SS".
Так а в чем проблема? "ß" и "SS" оба будут занимать 16 и 32 бита в char16_t и char32_t соответственно. Почему нельзя их in-place заменить?
Здравствуйте, greenpci, Вы писали:
G>Здравствуйте, McQwerty, Вы писали:
G>>>Во вторых, смотри char16_t и char32_t, которые были добавлены в С++11 с целью обеспечить фиксированную длину символа. MQ>>В некоторых языках есть некоторые извраты. Например для немецкого: ToUpper ("ß") == "SS".
G>Так а в чем проблема? "ß" и "SS" оба будут занимать 16 и 32 бита в char16_t и char32_t соответственно. Почему нельзя их in-place заменить?
Неа. "SS" — это два символа, т.е. 2 чара — это не компаунд, а именно что две стандартных буквы S(которые будут занимать 32 и 64 бита в втоем случае). А "ß" — один символ, один чар. И это далеко не единственный подобный изврат в юникоде. Хотя, может, С++11 умеет как-то хитро компоновать чары, что-то вроде utf-8, но не utf-8(иначе на кой хрен нужны 16 и 32 бита на чар?), но тогда работа с этим обернется адовым геморроем.
Не, ну можно воспринимать строку просто как контейнер каких-то-там байтов, которые желательно интерпритировать как строку, но в 21 веке это звучит диковато. А все из-за того, что кому-то очень хочется сэкономить на выделении памяти под модифицированную строку(вообще, имхо, строки должны быть иммутабельны, да и вообще иммутабельность желательна для подавляющего количества объектов кроме специальных случаев — решается сразу куча проблем).
Новости очень смешные. Зря вы не смотрите. Как будто за наркоманами подсматриваешь. Только тетка с погодой в завязке.
There is no such thing as a winnable war.
V>К тому же, MSVC вызывает библиотеку только для случая, когда количество копируемых байт на этапе компиляции неизвестно, а это достаточно редкий сценарий, который к тому же говорит, что в консерваитории что-то не так. ))
Что значит "редкий сценарий"? Программы работают с внешними данными, характер которых и размер на этапе компиляции по определению неизвестен. Иначе на кой хрен та программа вообще нужна?
Новости очень смешные. Зря вы не смотрите. Как будто за наркоманами подсматриваешь. Только тетка с погодой в завязке.
There is no such thing as a winnable war.
Здравствуйте, 0BD11A0D, Вы писали:
C>>Meanwhile in IDEA: http://blog.jetbrains.com/idea/2012/08/complete-static-methods-and-fields-with-the-new-intellij-idea-12-eap-build-12229/ BDA>Талант у человека — что ни напишет, все не в тему. Взять IDE от Java вместо CLion, притянуть поиск по именам в статических методах вместо ПОДБОРА ВСЕХ ПОДДЕРЖИВАЕМЫХ АЛГОРИТМОВ ПО ОБЪЕКТУ, а потом ололокать — это не говнопрограммистом надо быть, а я не знаю, кем.
Я понимаю, у вас в String запиханы ВСЕ методы, которые когда-либо работают со строкой. Для тех методов, которые со строками не работают по каким-то надуманным причинам — сделаны строковые обёртки.
А программы пишутся выбором методов после "MyNameIsVasja".ctrl-space. При этом заранее неизвестно что за метод нужен, программист всегда пробегает по всему списку методов и выбирает наиболее интересный.
Ну типа, надо вызвать disk.getInfo() и программист пишет "MyNameIsVasja".getDiskBlockInfo(disk). При этом интеллисенс очен вежливо подсказывает, какой именно disk должен попасть в параметр!
Да, я начинаю понимать всю всемогущность такой техники! Завтра же переписываю все свои программы!
Здравствуйте, Eugeny__, Вы писали:
G>>Так а в чем проблема? "ß" и "SS" оба будут занимать 16 и 32 бита в char16_t и char32_t соответственно. Почему нельзя их in-place заменить?
E__>Неа. "SS" — это два символа, т.е. 2 чара — это не компаунд, а именно что две стандартных буквы S(которые будут занимать 32 и 64 бита в втоем случае). А "ß" — один символ, один чар. И это далеко не единственный подобный изврат в юникоде. Хотя, может, С++11 умеет как-то хитро компоновать чары, что-то вроде utf-8, но не utf-8(иначе на кой хрен нужны 16 и 32 бита на чар?), но тогда работа с этим обернется адовым геморроем.
В таком случае, можно будет избежать только копирования из пункта 1.
E__>Не, ну можно воспринимать строку просто как контейнер каких-то-там байтов, которые желательно интерпритировать как строку, но в 21 веке это звучит диковато. А все из-за того, что кому-то очень хочется сэкономить на выделении памяти под модифицированную строку(вообще, имхо, строки должны быть иммутабельны, да и вообще иммутабельность желательна для подавляющего количества объектов кроме специальных случаев — решается сразу куча проблем).
Мне кажется С++ и остался для таких вот специфических вещей, если кому-то что-то особенное надо в 21 веке. Кому нужно все самому настроить, а не из коробки: High Frequency Trading, игры и наш случай.