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

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

Posts Tagged ‘math

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

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. Было бы интересно услышать мнение читателей насчет применимости всех этих идей.

Реклама

Written by Dmitri

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

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

Tagged with , ,