Подтвердить что ты не робот

Эффективность F # в научных вычислениях

Мне интересно, как производительность F # сравнивается с производительностью С++? Я задал аналогичный вопрос в отношении Java, и впечатление, которое я получил, было то, что Java не подходит для интенсивного числа строк.

Я читал, что F # должен быть более масштабируемым и более производительным, но как эта реальная производительность сравнивается с С++? конкретные вопросы о текущей реализации:

  • Насколько хорошо он работает с плавающей запятой?
  • Предоставляет ли он векторные инструкции
  • насколько он дружелюбен к оптимизации Составители?
  • Насколько велика печать печати в памяти? Предоставляет ли он мелкозернистый контроль над местностью памяти?
  • имеет ли он возможность распределять процессоры памяти, например Cray?
  • какие функции у него есть, что может представлять интерес для вычислительной науки, в которой задействована обработка тяжелых чисел?
  • Существуют ли реальные научные вычисления которые его используют?

Спасибо

4b9b3361

Ответ 1

  • F # вычисляет с плавающей запятой так же быстро, как это делает .NET CLR. Не сильно отличается от С# или других языков .NET.
  • F # не разрешает векторные инструкции самостоятельно, но если ваш CLR имеет API для них, F # не должен иметь проблем с его использованием. См. Например Моно.
  • Насколько я знаю, на данный момент есть только один компилятор F #, так что, возможно, вопрос должен быть "насколько хорош компилятор F #, когда дело доходит до оптимизации?". Ответ в любом случае "потенциально так же хорош, как компилятор С#, возможно, немного хуже на данный момент". Следует отметить, что F # отличается от, например, С# в своей поддержке встраивания во время компиляции, что потенциально позволяет использовать более эффективный код, основанный на дженериках.
  • Отпечатки пальцев памяти программ F # аналогичны изображениям других языков .NET. Объем контроля над распределением и сборкой мусора такой же, как на других языках .NET.
  • Я не знаю о поддержке распределенной памяти.
  • F # имеет очень приятные примитивы для работы с плоскими структурами данных, например. массивов и списков. Ищите экземпляр в содержимом модуля Array: map, map2, mapi, iter, fold, zip... Массивы популярны в научных вычислениях, я думаю, из-за их по своей природе хороших свойств локальности памяти.
  • Для пакетов научных вычислений с использованием F # вы можете посмотреть, что делает Джон Харроп.

Ответ 2

Мне интересно, как производительность F # сравнивается с производительностью С++?

Различается в зависимости от приложения. Если вы много используете сложные структуры данных в многопоточной программе, то F #, вероятно, будет большой победой. Если большая часть вашего времени проводится в жестких числовых циклах, мутирующих массивы, тогда С++ может быть в 2-3 раза быстрее.

Тематическое исследование: трассировщик лучей В моем тесте здесь используется дерево для иерархического выбора и числового кода пересечения лучей для создания выходного изображения. Этот показатель составляет несколько лет, а код С++ был улучшен десятками раз за эти годы и читается сотнями тысяч людей. Дон Симу в Microsoft удалось написать реализацию F #, которая немного быстрее, чем самый быстрый код С++ при компиляции с MSVC и распараллеливается с использованием OpenMP.

Я читал, что F # должен быть более масштабируемым и более производительным, но как эта реальная производительность сравнивается с С++?

Разработка кода намного проще и быстрее с F #, чем С++, и это касается оптимизации, а также обслуживания. Следовательно, когда вы начинаете оптимизировать программу, то такое же количество усилий принесет гораздо больший прирост производительности, если вы используете F # вместо С++. Однако F # является языком более высокого уровня и, следовательно, помещает нижний потолок в производительность. Поэтому, если у вас есть бесконечное время для оптимизации, вы должны теоретически всегда иметь возможность создавать более быстрый код на С++.

Это то же самое преимущество, что и у С++ по сравнению с Fortran, и Fortran, конечно же, занимался рукописным сборщиком.

Пример: QR-декомпозиция Это базовый численный метод из линейной алгебры, предоставляемый библиотеками, такими как LAPACK. Референсная реализация LAPACK - 2077 строк Fortran. Я написал реализацию F # в 80 строках кода, которые достигают такого же уровня производительности. Но эталонная реализация не является быстрой: реализации, настроенные на основе поставщиков, такие как Intel Math Kernel Library (MKL), часто в 10 раз быстрее. Примечательно, что мне удалось оптимизировать код F # намного выше производительности Intel, выполняемой на аппаратном обеспечении Intel, сохраняя мой код до 150 строк кода и полностью универсальным (он может обрабатывать одиночную и двойную точность, а также сложные и даже символические матрицы!): для высоких тонких матриц мой код F # до 3 раз быстрее, чем Intel MKL.

Обратите внимание, что мораль этого исследования не заключается в том, что вы должны ожидать, что ваш F # будет быстрее, чем библиотеки, настроенные на работу с производителями, но, скорее, даже такие эксперты, как Intel, будут пропускать продуктивные высокоуровневые оптимизации, если они будут использовать только более низкие уровни языки. Я подозреваю, что специалистам по численной оптимизации Intel не удалось полностью использовать parallelism, потому что их инструменты делают его чрезвычайно громоздким, в то время как F # делает его легким.

Насколько хорошо он работает с плавающей запятой?

Производительность похожа на ANSI C, но некоторые функции (например, режимы округления) недоступны в .NET.

Разрешает ли он векторные инструкции

Нет.

насколько он дружелюбен к оптимизации компиляторов?

Этот вопрос не имеет смысла: F # - это собственный .NET-язык .NET от Microsoft с одним компилятором.

Насколько велика печать печати в памяти?

Пустое приложение использует здесь 1.3Mb.

Предоставляет ли он мелкозернистый контроль над локальностью памяти?

Лучше, чем большинство безопасных для памяти языков, но не так хорошо, как C. Например, вы можете распаковывать произвольные структуры данных в F #, представляя их как "структуры".

он имеет емкость для процессоров с распределенной памятью, например Cray?

Зависит от того, что вы подразумеваете под "способностью". Если вы можете запустить .NET на этом Cray, тогда вы можете использовать передачу сообщений в F # (как и на следующем языке), но F # предназначена в первую очередь для настольных многоядерных машин x86.

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

Безопасность памяти означает, что вы не получаете ошибок сегментации и нарушений доступа. Поддержка parallelism в .NET 4 хороша. Возможность выполнять код "на лету" через интерактивный сеанс F # в Visual Studio 2010 чрезвычайно полезна для интерактивных технических вычислений.

Существуют ли реальные научные вычислительные реализации, которые его используют?

Наши коммерческие продукты для научных вычислений в F # уже имеют сотни пользователей.

Однако ваша линия опроса указывает, что вы думаете о научных вычислениях как высокопроизводительных вычислениях (например, Cray), а не о интерактивных технических вычислениях (например, MATLAB, Mathematica). F # предназначен для последнего.

Ответ 3

В дополнение к тому, что говорили другие, есть один важный момент в F # и parallelism. Производительность обычного кода F # определяется CLR, хотя вы можете использовать LAPACK из F #, или вы можете выполнять собственные вызовы с использованием С++/CLI как часть вашего проекта.

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

Что касается распределенных вычислений, вы можете использовать любую распределенную вычислительную инфраструктуру, доступную для платформы .NET. Существует проект MPI.NET, который хорошо работает с F #, но вы также можете использовать DryadLINQ, который является проектом MSR.

Ответ 4

Как и во всех сравнениях языков/производительности, ваш пробег сильно зависит от того, насколько хорошо вы можете кодировать.

F # является производной от OCaml. Я был удивлен, узнав, что OCaml очень много используется в финансовом мире, где производительность хруста в номере очень важна. Я был также удивлен, узнав, что OCaml - один из самых быстрых языков, с производительностью наравне с самыми быстрыми компиляторами C и С++.

F # построен на CLR. В CLR код выражается в виде байт-кода, называемого Common Intermediate Language. Таким образом, он извлекает выгоду из возможностей оптимизации JIT и имеет производительность, сравнимую с С# (но не обязательно С++), если код написан хорошо.

Код CIL может быть скомпилирован в собственный код на отдельном этапе перед запуском с использованием генератора собственных изображений (NGEN). Это ускоряет все последующие прогоны программного обеспечения, поскольку компиляция CIL-to-native больше не нужна.

Следует учитывать, что функциональные языки, такие как F #, имеют более декларативный стиль программирования. В каком-то смысле вы переопределяете решение на императивных языках, таких как С++, и это ограничивает возможность компилятора оптимизировать. Более декларативный стиль программирования теоретически может дать компилятору дополнительные возможности для алгоритмической оптимизации.

Ответ 5

Это зависит от того, какие научные вычисления вы делаете.

Если вы делаете traditional heavy computing, например. линейную алгебру, различные оптимизации, то вы не должны помещать свой код в .Net framework, по крайней мере, не подходящий в F #. Поскольку это на уровне алгоритма, большинство алгоритмов должны быть закодированы на императивных языках, чтобы иметь хорошую производительность при работе и использовании памяти. Другие упомянули параллель, я должен сказать, что это, вероятно, бесполезно, когда вы делаете вещи низкого уровня, подобные параллельной реализации SVD. Поскольку, когда вы знаете, как параллельно SVD, вы просто не будете использовать языки высокого уровня, Fortran, C или модифицированные C (например, cilk) - ваши друзья.

Однако многие научные вычисления сегодня не такие, какие-то приложения высокого уровня, например. статистические вычисления и интеллектуальный анализ данных. В этих задачах, помимо некоторой линейной алгебры или оптимизации, существует также множество потоков данных, IO, prepossessing, графика и т.д. Для этих задач F # действительно эффективна, благодаря своей лаконичности, функциональности, безопасности и простоте параллель и т.д.

Как отмечали другие,.NET хорошо поддерживает Platform Invoke, на самом деле довольно много проектов внутри MS используют .Net и P/Invoke вместе, чтобы улучшить производительность на шее бутылки.

Ответ 6

Я не думаю, что вы найдете много достоверной информации, к сожалению. F # по-прежнему является очень новым языком, поэтому даже если он идеально подходит для работы с большими рабочими нагрузками, все равно будет не так много людей, у которых есть значительный опыт для отчета. Кроме того, производительность очень сложна для точного измерения, а микрообъективы трудно обобщить. Даже в С++ вы можете увидеть драматические различия между компиляторами - вам интересно, совместим ли F # с любым компилятором С++ или с гипотетическим "наилучшим возможным" исполняемым С++?

Что касается конкретных тестов по сравнению с С++, вот некоторые возможные релевантные ссылки: O'Caml vs. F #: QR-декомпозиция; F # vs Неуправляемый С++ для параллельных вычислений. Обратите внимание, что как автор материала, связанного с F #, и как поставщик инструментов F #, автор имеет заинтересованность в успехе F #, поэтому возьмите эти претензии с солью.

Я думаю, что можно с уверенностью сказать, что будут некоторые приложения, где F # является конкурентоспособной во время исполнения и, вероятно, некоторые другие, где это не так. В большинстве случаев F #, вероятно, потребует больше памяти. Конечно, конечная производительность также будет сильно зависеть от умения программиста - я думаю, что F # почти наверняка будет более продуктивным языком для программирования для умеренно грамотного программиста. Кроме того, я думаю, что на данный момент CLR на Windows работает лучше, чем Mono, в большинстве ОС для большинства задач, что также может повлиять на ваши решения. Конечно, поскольку F #, вероятно, легче распараллелить, чем С++, это также будет зависеть от типа оборудования, которое вы планируете запускать.

В конечном счете, я думаю, что единственный способ ответить на этот вопрос - написать код F # и С++, представляющий тип вычислений, которые вы хотите выполнить и сравнить.

Ответ 7

Вот два примера, которыми я могу поделиться:

У меня есть крупномасштабный логистический регрессионный решатель с использованием оптимизации LBFGS, который закодирован на С++. Реализация хорошо настроена. Я изменил код на код в С++/CLI, т.е. Скомпилировал код в .Net. Версия .Net в 3 - 5 раз медленнее, чем наивная скомпилированная в разных наборах данных. Если вы код LBFGS в F #, производительность не может быть лучше, чем С++/CLI или С# (но будет очень близко).

У меня есть еще одна запись в Почему F # является языком для интеллектуального анализа данных, хотя это не совсем связано с проблемой производительности, которую вы здесь затрагиваете, весьма связан с научными вычислениями в F #.

Ответ 8

Если я скажу "спроси снова через 2-3 года", я думаю, что полностью ответит на ваш вопрос:-)

Во-первых, не ожидайте, что F # будет отличаться от С#, если вы не делаете некоторые запутанные рекурсии специально, и я бы предположил, что вы не с тех пор, как вы спросили о цифрах.

Точка с плавающей запятой должна быть лучше, чем Java, поскольку CLR не нацелена на одноплатформенность между платформами, а это означает, что JIT будет работать до 80 бит, когда это возможно. С другой стороны, вы не контролируете это, кроме наблюдения за количеством переменных, чтобы убедиться, что там достаточно FP-регистров.

Если вы достаточно громко кричите, возможно, что-то произойдет через 2-3 года, так как Direct3D входит в .NET как обычный API, так как код С#, выполненный в XNA, запускается на Xbox, который находится так близко от голого металла, вы можете получить с CLR. Это все равно означает, что вам понадобится сделать некоторый промежуточный код самостоятельно.

Так что не ожидайте CUDA или даже способности просто связывать библиотеки NVIDIA и идти. У вас было бы гораздо больше удачи, пытаясь использовать этот подход с Haskell, если по какой-то причине вы действительно нуждаетесь в "функциональном" языке, поскольку Haskell был разработан, чтобы быть удобным для общения из чистой необходимости.

Mono.Simd уже упоминался, и, хотя он должен быть обратно переносимым в CLR, для его выполнения может быть довольно некоторая работа.

В коде social.msdn можно использовать некоторый код при использовании SSE3 в .NET, с С++/CLI и С#, приходить массив blitting, вводя SSE3-код для perf и т.д.

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

Вещь, которая может стоить вам больше, если вы хотите попробовать что-то скоро, PhysX.Net на codeplex. Не ожидайте, что он просто распакуется и сделает магию. Тем не менее, у меня в настоящее время активный автор, и код является как нормальным С++, так и С++/CLI, и yopu, возможно, получит некоторую помощь от автора, если вы хотите вдаваться в подробности и, возможно, использовать аналогичный подход для CUDA. Для полной скорости CUDA вам все равно нужно будет скомпилировать свои собственные ядра, а затем просто подключиться к .NET, так что чем проще эта часть, тем счастливее вы будете.

Существует CUDA.NET lib, которая должна быть бесплатной, но страница дает только адрес электронной почты, поэтому ожидайте присоединения некоторых строк, и хотя автор пишет blog, он не особо рассуждает о том, что внутри lib.

О, и если у вас есть бюджет, вы можете дать Psi Lambda вид (KappaCUDAnet - это часть .NET). По-видимому, они собираются поднять цены в ноябре (если это не трюк продаж: -)

Ответ 9

Последнее, что я знал, большинство научных вычислений все еще было сделано в FORTRAN. Это еще быстрее, чем что-либо еще для задач линейной алгебры - не Java, не C, а не С++, а не С#, а не F #. LINPACK хорошо оптимизирован.

Но замечание о том, что ваш пробег может отличаться, справедливо для всех эталонных тестов. Утверждения о платьях (кроме моего) редко бывают истинными.

Ответ 10

Во-первых, C значительно быстрее, чем С++. Поэтому, если вам нужна такая скорость, вы должны сделать lib и т.д. в c.

Что касается F #, то большинство контрольных точек используют Mono, который до 2 * медленнее, чем MS CLR, из-за частичного использования GC GC boehm (у них есть новый GC и LVVM, но они все еще незрелые, не поддерживают дженерики и т.д.),

.NEt-языки скомпилированы в IR (CIL), которые скомпилируются в собственный код так же эффективно, как С++. Существует одна проблема, с которой сталкиваются большинство языков GC, и это большие количества изменяемых записей (это включает в себя С++.NET, как указано выше). И есть определенный набор научных заданий, который требует этого, когда нужно, возможно, следует использовать родную библиотеку или использовать шаблон Flyweight для повторного использования объектов из пула (что сокращает количество записей). Причина в том, что в .NET CLR существует барьер записи, где при обновлении ссылочного поля (включая поле) он будет устанавливать бит в таблице, говоря, что эта таблица изменена. Если ваш код состоит из множества таких записей, он пострадает.

Это говорит о том, что .NET-приложение, такое как С#, используя множество статических кодов, structs и ref/out в структурах, может давать C как производительность, но очень сложно закодировать это или поддерживать код (например, C).

Где F # светит, однако, является парралелизмом по неизменяемым данным, которые идут рука об руку с большим количеством проблем на основе чтения. Стоит отметить, что большинство эталонных тестов намного выше, чем в реальных приложениях.

Что касается плавающей запятой, вы должны использовать альтернативный lib (то есть .Net) для oCaml из-за медленного. C/С++ позволяет быстрее для более низкой точности, которую oCaml не делает по умолчанию.

Наконец, я утверждаю, что язык высокого уровня, такой как С#, F # и правильное профилирование, даст вам betetr pefromance, чем c и С++ для одного и того же времени разработчика. Если вы измените шею бутылки на вызов c lib pinvoke, вы также получите C как производительность для критических областей. Тем не менее, если у вас есть неограниченный бюджет и больше заботитесь о скорости, то обслуживание, а не C, - это путь (не С++).