yigal_s: (general)
[personal profile] yigal_s
Valgrind is in essence a virtual machine using just-in-time (JIT) compilation techniques, including dynamic recompilation. Nothing from the original program ever gets run directly on the host processor. Instead, Valgrind first translates the program into a temporary, simpler form called Intermediate Representation (IR), which is a processor-neutral, SSA-based form. After the conversion, a tool (see below) is free to do whatever transformations it would like on the IR, before Valgrind translates the IR back into machine code and lets the host processor run it. Even though it could use dynamic translation (that is, the host and target processors are from different architectures), it doesn't. Valgrind recompiles binary code to run on host and target (or simulated) CPUs of the same architecture.

Мне стыдно, что не знал этого раньше. Эти черти перехватывают каждое обращение к памяти, на уровне базовой платформы инструментации (под которую можно писать клиенты-плагины), после чего поиск data-races - вполне решаемая задача, что собственно, уже и имплементировано. О всякой прочей фигне, вроде поиска дедлоков, мемликов и говорить не приходится. До кучи, решаются задачи поиска обращений к непроинициализированной памяти и выхода за пределы памяти проаллоцированной. Вот так. Одним махом.

Еще, правда, не понятно как они делают на этой платформе профайлер, раз уж они пределывают весь код процесса. Неужели же эмулируют конвеер процессора? ))).

Date: 2013-08-03 01:54 am (UTC)
From: [identity profile] spamsink.livejournal.com
Вот так живешь и не знаешь, какую чуть не с детства известную вещь стоит рассказывать в ЖЖ, а какую - нет, потому что баянистом обзовут. Я участвовал в написании упрощенного варианта этого (многопоточность была, JIT был, инструментовка была, IR не было) для СПАРКа 15-16 лет назад http://compilers.iecc.com/comparch/article/97-10-153 вместе с этим Грегом Люком.

Date: 2013-08-03 02:50 am (UTC)
From: [identity profile] spamsink.livejournal.com
Еще бы! А как иначе разработчикам процессоров экспериментировать с разными механизмами кеширования, префетчинга, предсказания переходов и т.п.?

Date: 2013-08-03 03:08 am (UTC)
From: [identity profile] spamsink.livejournal.com
Если ждать, пока весь SPECint и весь SPECfp проинтерпретируется тупым интерпретатором - можно раньше сдохнуть. А даже первая версия SPARC Shade в 1993 году была вот какая: Running on a SPARC and simulating a SPARC, SPEC 89 benchmarks run about 2.3 times slower for floating-point programs and 6.2 times slower for integer programs.

Date: 2013-08-03 03:35 am (UTC)
From: [identity profile] spamsink.livejournal.com
Так ведь инструментация задается статически, поэтому JIT просто вставляет необходимые вызовы моделирующих функций в генерируемые линейные участки, и только для команд, требующих моделирования (скажем, кеша - для чтений/записей, предсказания переходов - для команд перехода, и т.п.), делов-то.

Date: 2013-08-03 03:52 am (UTC)
From: [identity profile] spamsink.livejournal.com
Уже 20 лет как применяют, говорю как краевед. Сам по себе JIT по сравнению с интерпретацией дает выигрыш на порядки; чтобы этот выигрыш перестал быть существенным, моделирующие функции должны быть ну о-о-очень дорогие.

Date: 2013-08-03 01:57 am (UTC)
From: [identity profile] spamsink.livejournal.com
Профайлер по умолчанию считает функции и инструкции, но можно еще и кэш симулировать.

Date: 2013-08-03 02:51 am (UTC)
From: [identity profile] spamsink.livejournal.com
Вопрос, начиная с какой точности симуляции получаются diminishing results. Много ли толку от профиля, например, который на 5% точнее, но работает в 10 раз медленнее?

Date: 2013-08-04 08:28 am (UTC)
From: [identity profile] igor-abramov.livejournal.com
Я вот тут подумал немного на эту тему. На самом деле, абсолютно точная оптимизация на уровне ИСХОДНОГО кода с учетом всех тонкостей конвееров и прочего нужна не так часто (порываюсь написать, что исключительно редко).

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

А вот оптимизировать для некоторой единой абстрактной машины, не так уж далеко ушедшей от реального железа, но существенно более гладкой --- пожалуй разумный компромисс. Эта машина будет соответствовать некому образу процессора, имеющемуся в голове озабоченного микроэффективностью С/С++ программиста.

Ну о оптимизации на уровне исходного кода для таких вещей имеют обычно более благообразный вид.

Date: 2013-08-04 04:40 pm (UTC)
From: [identity profile] igor-abramov.livejournal.com
Если мы программируем на C/C++ мало чем можем влиять на конвееры, потому, что компилятор весьма агрессивно переупорядочивает код. (За очевидными исключениями, когда мы используем asm директивы, ну и некоторые интринсики могут необосновано смутить кодогенератор).

Улучшенные интелом версии gcc одно время давали выигрыш процентов до 20. Вроде gcc и clang прибавили в последнее время, но я не изучал текущее положение дел.

Вот за чем можно следить, так это за локальностью и порядком обращений к памяти. Правильно разложенные (и выровненные) поля в структурах данных, возможно, даже поля следующие в порядке обращения к ним в самом типичном случае.

Date: 2013-08-04 05:15 pm (UTC)
From: [identity profile] igor-abramov.livejournal.com
Чисто теоретически, да, такая аномалия возможна, особенно на уже изрядно прооптимизированном коде.
Ну на этот случай есть Intel Vtune . Я его очень успешно использовал для оптимизации кода, генерируемого Just-In-Time.

Date: 2013-08-04 09:29 pm (UTC)
From: [identity profile] igor-abramov.livejournal.com
Фишка в том, что Vtune строит весьма точный профиль но под конкретный процессор. А вот процессоры разных микроархитектур от интела (про АМД не вспоминаем, но так уж давно и это было очень актуально) умеют отличаться, и в некоторых областях (достаточно экзотических, правда) очень сильно.

И вот в ситуации, когда мне нужно профильнуть код относительно многих процессорных семейств, в том числе и не вышедших, штука типа Valgrind может оказаться более полезной.
Edited Date: 2013-08-04 09:30 pm (UTC)