Я про выделение мышкой диапазона элементов (или диапазонов в комбинациях с кнопками Ctrl или Shift), с отображением области (прямоугольной) выделения.
Стандартное поведение для report list в Windows (вот этот затемнённый прямоугольник вроде называется rubber-band, а действие по выделению items таким способом band selection, но я могу сильно ошибаться, не силён в терминологии).
Оффтопик, конечно, но мне очень интересна реализация вот какой штуки: у QTreeView нет такой фичи как band selection (из QTreeView можно сделать report list, если возникнет вопрос «зачем это надо?»). Как правильно реализовать band selection? Может быть подскажете готовую реализацию? Или общее направление для изучения? (В менеджере KDE Dolphin сделано то, что надо, но, честно сказать, мне сложно разобраться что за что отвечает)
Осталось только заметить, что косвенный переход по адресу в таблице по сути условный переход (и вообще адресация памяти это выбор с условием):
если x равно 0, вернуть содержимое ячейки с номером 0
если x равно 1, вернуть содержимое ячейки с номером 1
и т.п.
Ещё в догонку по поводу доступа к вектору и массиву:
массив выделяется, например, так
T* p = new T[size];
и компилятор запросто кэширует указатель в регистре, и при использовании p[] ему не нужно лишних телодвижений (просто сложение указателя со смещением, что на x86 поддерживается командами адресации навроде [rcx + rax]).
Вектор сложней по устройству:
class v
{
T* p;
size_t size;
}
то есть при обращении v[], сначала нужно загрузить в регистр адрес объекта v, а потом по смещению выбрать уже адрес массива и индексировать, добавляется лишняя операция.
В тривиальных случаях адреса и объекта и массива размещаются в регистрах (или они загружаются в регистры непосредственно перед циклом) и не надо тратить время на два обращения. Но в более сложных случаях, когда участвуют много векторов сразу — регистров, видимо, не хватает и получается оверхед на получения адреса массива из памяти. Возможно это так же влияет на применимость loop unrolling.
Посмотрел на сгенерированный машинный код (-Fa -FAs) array и std_vector (release, Microsoft ® C/C++ Optimizing Compiler Version 16.00.40219.01 for x64).
Листинги близки по содержанию, но видно, что в случае std_vector во-первых используется больше переменных в памяти. Во-вторых в array вовсю используется loop unrolling, а в случае с std_vector — нет. В-третьих случае с array адрес массива берётся напрямую из переменной (а некоторые кэшируются непосредственно в регистрах), а в случае в std::vector сначала из переменной считывается адрес объекта vector, а потом уже из памяти, где расположен объект считывается адрес массива (это какбэ очевидно из устройства vector).
Это то, что видно невооружённым взглядом. Думаю, что это проблема оптимизатора, а не, собственно, std::vector (хотя автору всё равно кто виноват, ему результаты нужны, а не подробности работы компилятора =)
Попробовал написать тривиальный пример с std::vector — компилятор оптимизирует один в один с array. Стал его постепенно усложнять (добавлять вложенных циклов и зависимых векторов) и, с определённого момента оптимизатор перестал справляться и начались расхождения с версией array. Затрудняюсь в причинах такого поведения, но факт, так сказать налицо. Оптимизировать шаблонный код сложней чем линейный код в стиле C.
Дело в том, что сама по себе обёртка может быть полезна и приятна. Например для использования «uxtheme.dll» — поддержка theme, которая появилась в XP, но не было в предыдущих версиях windows часто использовали подобный код (впрочем, проще это решается использованием delayed load).
В данном случае это просто ненужные костыли. Дело даже не в оверхеде вызова, а в том, что «я не разобрался как надо делать, поэтому сделал свой велосипед».
Конечно, иногда возникают проблемы с линковкой динамических библиотек (из-за name mangling например), но они проще решаются написанием соответствующего .def-файла.
Программы в нативном коде прошли все эти этапы эволюционной борьбы «защита-взлом» с десяток лет назад. Результаты неутишительные — защита/обфускация кода выполняемого на стороне клиента практически бессмысленна. Очередной виток. Ну-ну.
Создаём инструменты для обфускации? PROFIT! Ломаем то, что наделали обфускаторы? PROFIT! И т.д. и т.п. А идея проста — защита кода на стороне клиента ненужна.
Ухты, с недавних пор механизмы описанные в datasheet стали волшебством?! Ужас просто: «я прочёл документацию на микроконтроллер и узнал, что у него есть служебные ноги, которые можно использовать для собственных целей после того, как микросхема инициализированна! Щаз я вам расскажу!». Ожидаю статей «В ПЛИС Altera можно использовать ноги, которые используются для загрузки прошивки через EEPROM (и некоторые другие служебные ноги)», «У TMS-ов (процессоры Texas Instrument) можно использовать ноги, которые используются для загрузки прошивки через EEPROM (да и вообще там много multipurpose pins)» и т.п.
Таких чипов, где назначение ног в момент инициализации одно, а после другое — мильоны (да практически любой Ethernet 3Speed PHY и т.п.). Аффтору уже выдали значок «Капитан очевидность III ранга»?
Да вроде ClearType (tm) это торговая марка конкретной реализации технологии субпиксельного сглаживания (есть ещё, например, CoolType от Adobe, Quartz от Apple и т.д.)
Так что я сказал, то что хотел сказать.
Ещё никто не рассказал, почему отключают сглаживание шрифтов для скриншотов?
Матрицы бывают с разным расположением RGB-компонент пикселя. Поэтому, скриншот шрифта с субпиксельным сглаживанием для матрицы с RGB последовательностью, будет смотреться ужасно на BGR (VRGB, VBGR и т.п.). И будет смотреться странно на CRT-мониторах (хотя не знаю, какой процент использует CRT сейчас, может быть это неактуально). Поэтому субпиксельное сглаживание использовать для скриншотов не стоит (но можно использовать обычное сглаживание).
OS: Win7x64, Mem: 4 ГБ, CPU: Intel® Core(TM)2 CPU 6420 @2.14GHz. Антивирусов и прочей фигни нет.
Солюшен из двух проектов, в одном 40 файлов, в другом 18. Общий размер исходных файлов (*.cpp + *.h) ~300 КБ. По моим меркам — мелочь (собирается за несколько секунд).
Анализ занял ~7 минут.
(Пока мерил заметил, что вызывается компилятор для препроцессинга, появляются файлы *.i =).
Ага, я что-то на слово «бесплатно» слишком радостно отреагировал. =)
Проанализировал несколько своих проектов: предупреждений нет. Либо я слишком правильно пишу код, либо наоборот слишком неправильно для статического анализа. =)
P.S. Больше тестировать не хочется, уж очень долго идёт анализ.
P.P.S. Понимаю, что анализ это не слишком частая операция, но ведь хочется проверить сразу на всём что есть. =)
1 1 License information not found. Starting trial version. Only several errors are shown. TNLab 0 False
0 2 V003 Unrecognized error found: Cannot read safe type list from file c:\users\lynxy\appdata\roaming\pvs-studio\safe_types.txt TNLab ChangeTypeDlg.cpp 1 False
И так далее, все ошибки V003.
Использую MSVS2005, Win7x64. Указанного файла там действительно нет.
Видимо что-то не так с инсталлятором, поскольку установились файлы в профиль администратора (при запуске инсталлятора он потребовал админские права), а работаю то я под обычным юзером (чего и вам рекомендую =).
Стандартное поведение для report list в Windows (вот этот затемнённый прямоугольник вроде называется rubber-band, а действие по выделению items таким способом band selection, но я могу сильно ошибаться, не силён в терминологии).
если x равно 0, вернуть содержимое ячейки с номером 0
если x равно 1, вернуть содержимое ячейки с номером 1
и т.п.
массив выделяется, например, так
T* p = new T[size];
и компилятор запросто кэширует указатель в регистре, и при использовании p[] ему не нужно лишних телодвижений (просто сложение указателя со смещением, что на x86 поддерживается командами адресации навроде [rcx + rax]).
Вектор сложней по устройству:
class v
{
T* p;
size_t size;
}
то есть при обращении v[], сначала нужно загрузить в регистр адрес объекта v, а потом по смещению выбрать уже адрес массива и индексировать, добавляется лишняя операция.
В тривиальных случаях адреса и объекта и массива размещаются в регистрах (или они загружаются в регистры непосредственно перед циклом) и не надо тратить время на два обращения. Но в более сложных случаях, когда участвуют много векторов сразу — регистров, видимо, не хватает и получается оверхед на получения адреса массива из памяти. Возможно это так же влияет на применимость loop unrolling.
Листинги близки по содержанию, но видно, что в случае std_vector во-первых используется больше переменных в памяти. Во-вторых в array вовсю используется loop unrolling, а в случае с std_vector — нет. В-третьих случае с array адрес массива берётся напрямую из переменной (а некоторые кэшируются непосредственно в регистрах), а в случае в std::vector сначала из переменной считывается адрес объекта vector, а потом уже из памяти, где расположен объект считывается адрес массива (это какбэ очевидно из устройства vector).
Это то, что видно невооружённым взглядом. Думаю, что это проблема оптимизатора, а не, собственно, std::vector (хотя автору всё равно кто виноват, ему результаты нужны, а не подробности работы компилятора =)
Попробовал написать тривиальный пример с std::vector — компилятор оптимизирует один в один с array. Стал его постепенно усложнять (добавлять вложенных циклов и зависимых векторов) и, с определённого момента оптимизатор перестал справляться и начались расхождения с версией array. Затрудняюсь в причинах такого поведения, но факт, так сказать налицо. Оптимизировать шаблонный код сложней чем линейный код в стиле C.
В данном случае это просто ненужные костыли. Дело даже не в оверхеде вызова, а в том, что «я не разобрался как надо делать, поэтому сделал свой велосипед».
Конечно, иногда возникают проблемы с линковкой динамических библиотек (из-за name mangling например), но они проще решаются написанием соответствующего .def-файла.
Создаём инструменты для обфускации? PROFIT! Ломаем то, что наделали обфускаторы? PROFIT! И т.д. и т.п. А идея проста — защита кода на стороне клиента ненужна.
Таких чипов, где назначение ног в момент инициализации одно, а после другое — мильоны (да практически любой Ethernet 3Speed PHY и т.п.). Аффтору уже выдали значок «Капитан очевидность III ранга»?
Так что я сказал, то что хотел сказать.
Видел мониторы с не RGB. Один раз и издалека. =)
Матрицы бывают с разным расположением RGB-компонент пикселя. Поэтому, скриншот шрифта с субпиксельным сглаживанием для матрицы с RGB последовательностью, будет смотреться ужасно на BGR (VRGB, VBGR и т.п.). И будет смотреться странно на CRT-мониторах (хотя не знаю, какой процент использует CRT сейчас, может быть это неактуально). Поэтому субпиксельное сглаживание использовать для скриншотов не стоит (но можно использовать обычное сглаживание).
Солюшен из двух проектов, в одном 40 файлов, в другом 18. Общий размер исходных файлов (*.cpp + *.h) ~300 КБ. По моим меркам — мелочь (собирается за несколько секунд).
Анализ занял ~7 минут.
(Пока мерил заметил, что вызывается компилятор для препроцессинга, появляются файлы *.i =).
Проанализировал несколько своих проектов: предупреждений нет. Либо я слишком правильно пишу код, либо наоборот слишком неправильно для статического анализа. =)
P.S. Больше тестировать не хочется, уж очень долго идёт анализ.
P.P.S. Понимаю, что анализ это не слишком частая операция, но ведь хочется проверить сразу на всём что есть. =)
0 2 V003 Unrecognized error found: Cannot read safe type list from file c:\users\lynxy\appdata\roaming\pvs-studio\safe_types.txt TNLab ChangeTypeDlg.cpp 1 False
И так далее, все ошибки V003.
Использую MSVS2005, Win7x64. Указанного файла там действительно нет.
Видимо что-то не так с инсталлятором, поскольку установились файлы в профиль администратора (при запуске инсталлятора он потребовал админские права), а работаю то я под обычным юзером (чего и вам рекомендую =).
А как такое возможно?
Ещё плюшка: Shift+F11 (Step out), возврат в точку вызова функции. Удобно шарахаться по call stack.