Дмитpий Hecтepук

Блог о программировании — C#, F#, C++, архитектура, и многое другое

Нужен ли математикам статический анализ?

10 комментариев

Есть такая профессия, в которой люди на 50% процентов занимаются программированием, но при этом сидят на порой весьма “несовременных” технологиях, пишут в основном на С++, и никаких особых бенефитов от IDE вообще не имеют. И при этом не жалуются. В этом посте – про то, кто эти люди, чем они заниматся и чем мы можем сделать их жизнь лучше.

Знакомьтесь – квонты

Квонт, он же quant (quantitative analyst – численный, так сказать, аналитик) — это человек, который занимается применением математики в финансах, часто – для создания торговых систем, т.е. программ, которые занимаются автоматизированной торговлей на бирже. Эти люди – чаще всего магистры или PhD в области физики (да-да) или математики (в частности, с дипломами вроде MFE – Masters in Financial Engineering), в некоторых случаях, с дипломом CQF (один из очень небольшого кол-ва “неакадемических” дипломов) или даже с MBA Finance или а ля.

Квонты (я бы называл их квантами) программируют в очень узком ключе – их в большинстве случаев не волнуют новые тренды в Asp.Net или новых языках вроде Scala или D. Они живут в совершенно другой реальности, где доминантным маст-хэв языком был, есть и будет С++. Конечно, есть варинты (например, вспомним Jane Street и их любовь к OCaml), но суть остается одна – эти разработчики привыкли работать с достаточно ограниченным tool support, и не особо от этого страдают. Ведь согласитесь, для того чтобы эффективно выполнять математические рассчеты нужно лишь чтобы у вас худо-бедно работал intellisense, и то, это не так критично если нужно вызвать что-то вроде std::min().

Соответственно, текущее положение вещей наводит на мысль, что людям которые используют в основном C++ (а также MATLAB, VBS, R, ну и другие языки на вкус) tool support как бы не очень нужен.

И все же…

Приведу конкретный пример. На многих графических устройствах, операция a*x+b оптимизирована и проходит быстрее, чем умножение и сложение отдельно. Соответственно, когда я работаю с GPU.NET, у меня есть в R2P контекстное действие, которое превращает все, что похоже на “умножение-в-сложении” на вызов вроде DeviceMath.MultiplyAdd(a, x, b). Мелочь, а приятно, и программу ускоряет.

И это далеко не частный случай. Вот еще пример – допустим что вы попросили студента за еду реализовать вам ряд формул в коде, и студент в качестве реализации написал что-то вроде y = a * Math.Pow(x, 2.0) + b * x. Бред, не так ли?

И тут снова можно включить “электронный мозг” статического анализатора и начать помогать несчастному разработчику. Для начала ему нужно объяснить, что считать ряды Тэйлора в подобном случае раз, эээ, в 50 медленнее чем сделать x*x. Но даже объяснив это, вы получите вот такой результат:

y = a * x * x + b * x;

Это тоже не очень-то эффективно. Ведь тут целых 3 умножения, хотя можно обойтись двумя:

y = x * (a * x + b);

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

А это имеет смысл?

Действительно, кому нужна скорость? Ну, наблюдения показывают что ряд задач (например, Монте-Карло симуляции) очень любят кушать CPU. Микрооптимизация вычислений – это как раз то, что позволит аналитику протестировать свою стратегию быстрее, на большем объеме данных.

Еще одна полезная, хотя и тривиальная вещь – это рефакторинги с уклонов в сторону параллелизации – например рефакторинг for и foreach циклов в параллельные с сохранением правильной семантики. То есть, если разработчик написал

int [] elems = new int[] { ⋮ };
int sum = 0;
foreach (var e in elems) sum += e;

то почему бы нам не дать ему возможность отрефакторить этот цикл в параллельный:

Parallel.ForEach(elems, () => 0, 
                 (n, loopState, localSum) => 
                 {
                   localSum += n;
                   return localSum;
                 },
                 localSum => Interlocked.Add(ref sum, localSum));

У меня в R2P уже реализованы некоторые приведения простых циклов в параллельные, но это большая задача, и за один день ее не решить.

Другие языки?

Я привел пример поддержки C#, т.к. не знаю доступной инфраструктуры для написания рефакторингов для С++ или (это было бы еще интересней) для CUDA C. Было бы интересно услышать мнение читателей насчет применимости всех этих идей.

Advertisements

Written by Dmitri

18 августа 2011 в 22:22

Опубликовано в .NET

Tagged with , ,

комментариев 10

Subscribe to comments with RSS.

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

    Dmitry Timofeev

    18 августа 2011 at 23:09

    • То же самое относится к Parallel.ForEach. Например, параллельное умножение матриц имеет смысл только для размерностей > 30 (примерно).

      Alek

      19 августа 2011 at 11:18

      • Размерности мы сами не сможем детектировано, равно как и предстазать то, с какими параметрами вычисления будут работать быстрее всего. Но вот предоставить понятные рефакторинги для того чтобы пользователь, если ему нужно, мог перевести простой цикл в параллельный мы можем.

        Dmitri

        19 августа 2011 at 11:39

  2. А откуда такая любовь к английским словам?
    Теперь по сути. Для многих важно удобство работы с языком. Кванты из вашей статьи думают на с++ и это их устраивает. А переучивание приведет к тому, что они будут думать о языке, а не о задаче.

    Anatoliy Sviridenkov (@anatoliy_svt)

    19 августа 2011 at 3:20

    • А откуда такая любовь к английским словам?

      14 лет прожитых в Англии дают о себе знать.

      Теперь по сути. Для многих важно удобство работы с языком. Кванты из вашей статьи думают на с++ и это их устраивает. А переучивание приведет к тому, что они будут думать о языке, а не о задаче.

      А я не предлагаю им язык менять. Просто думаю, возможно нам стоит снова задуматься о С++.

      Dmitri

      19 августа 2011 at 11:32

      • Конечно стоит:) О нем и забывать не стоило.

        MS в этом плане молодцы, они на С++ не забили и сейчас VC++2010 является один из лучших компилеров native C++, с поддержкой приличного количества фич из C++ 0x (фу ты, уже можно его называть C++ 11).

        Плюс, VC++2010 поддерживает ряд расширений для параллельной работы. Там же даже TPL есть, с интерфейсом очень похожим на TPL из .net framework. В общем, там очень и очень много интересного в неуправляемом мире:)

        Sergey Teplyakov

        19 августа 2011 at 11:57

        • Первое что я делаю как только начинаю работать с С++ — это заменяю Майкрософтовский стэк Интелевским. Так что конкретно в Майкровостовском С++ компиляторе я помню лишь то, что в те годы когда я усиленно штудировал книгу Generative Programming, компилятор МС не мог скомпилировать и половины из примеров в книге. В те времена были правда другие игрушки — KAI C++, Metroworks и так далее. Сейчас всем рекоммендую обратить внимание на «стэк Intel» — не только компилятор, профилятор и так далее, но также на библиотеки, в частности Math Kernel Library и Threading Building Blocks. Кстати, TBB — это как бы аналог PPL.

          Dmitri

          19 августа 2011 at 12:47

  3. Сейчас, видимо, являюсь таким квонтом — много финансовой аналитики. Основной язык C#. Думаю о внедрении, хотя бы в небольших дозах(библиотеках), F#.
    Это должно частично решить проблему подобных рефакторингов, дать возможность писать на более «математическом» уровне.
    Т.е. о переходе на C++ и речи нет, скорее есть необходимость перевода legacy C++ кода на C#/F#.
    Но для внедрения F# хотел бы найти больше информации об успешной или неуспешном опыте использоваия этого языка в финансовых вычислениях на промышленном проекте. В первую очередь, конечно, интересует скорость и удобство поддержки. Есть ли у кого-нибудь такие данные?

    Alek

    19 августа 2011 at 12:16

    • А вот эти данные вам мало кто даст. Как я написал, финансовые учреждения пока рассматривают F# как козырную карту. А карты они раскрывать не любят. С другой стороны, критика Jane Street о том что F# делает безумное кол-во аллокаций уместна, т.к. любой функциональный конструкт порождает объект. Например, если вы передаете оператор (+) как параметр, вы на самом деле создали struct который этот (+) представляет.

      Dmitri

      19 августа 2011 at 12:50

      • Вот и мне пока не совсем понятны козыри F# в реальном мире.
        Спасибо за ответ и ссылку на Jane Street. Буду следить за их успехами, а так же за http://cufp.org/

        Alexander Burdin

        19 августа 2011 at 13:46


Оставить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

%d такие блоггеры, как: