Python против C ++ для приложения, которое делает разреженную линейную алгебру - PullRequest
4 голосов
/ 21 сентября 2010

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

Я подумываю перейти на Python, чтобы упростить кодирование самого приложения, поскольку кажется, что библиотека Boost (легкая библиотека линейной алгебры C ++) в любом случае не особенно быстра.Это исследование / подтверждение концепции приложения, поэтому допустимо некоторое снижение скорости выполнения (так как я предполагаю, что C ++ почти всегда будет превосходить Python), если время кодирования также значительно сокращается.

По сути, я 'ищу общий совет от людей, которые раньше пользовались этими библиотеками.Но конкретно:

1) Я нашел scipy.sparse и и pySparse.Рекомендуются ли эти (или другие библиотеки)?

2) Какие библиотеки помимо Boost рекомендуются для C ++?Я видел множество библиотек с интерфейсами C, но, опять же, я стремлюсь сделать что-то с низкой сложностью, если смогу получить относительно хорошую производительность.

3) В конечном счете, Python будет в некоторой степени сопоставим с C ++с точки зрения скорости выполнения для операций линейной алгебры?Мне нужно будет сделать много-много операций по линейной алгебре, и если замедление будет значительным, то мне, вероятно, даже не стоит пытаться сделать это переключение.

Заранее благодарю за любую помощь и предыдущий опыт, который вы можете связать.

Ответы [ 5 ]

7 голосов
/ 21 сентября 2010

Мой совет - полностью протестировать алгоритм в Python, прежде чем переводить его на любой другой язык (в противном случае вы рискуете преждевременно оптимизировать плохой алгоритм). Как только вы четко определили лучший интерфейс для своих проблем, вы можете выделить его для внешнего кода.

Позвольте мне объяснить.

Предположим, что ваш последний алгоритм состоит из набора чисел в формате (строка, столбец, значение) и, скажем, вычисления SVD соответствующей разреженной матрицы. Тогда вы можете оставить весь интерфейс для Python:

class Problem(object):
   def __init__(self, values):
       self.values = values

   def solve(self):
       return external_svd(self.values)

где external_svd - это оболочка Python для подпрограммы Fortran / C / C ++, которая эффективно вычисляет svd по заданной матрице в формате (строка, столбец, значение) или что-либо еще, что плавает в вашей лодке.

Опять же, сначала попробуйте использовать numpy и scipy и любой другой стандартный инструмент Python. Только тогда, после того, как вы профилировали свой код, вы должны написать реальную оболочку external_svd.

Если вы пойдете по этому пути, у вас будет модуль, который удобен для пользователя (пользователь взаимодействует с Python, а не с Fotran / C / C ++), и, что наиболее важно, вы сможете использовать разные серверные части: external_svd_lapack, external_svd_paradiso, external_svd_gsl и т. Д. (По одному на каждый выбранный вами сервер).

Что касается разреженных библиотек линейной алгебры, проверьте Intel Math Kernel Library , PARADISO разреженный решатель , Harwell Subroutine Library (HSL) , называемый "MA27 ». Я успешно использовал их для решения очень редких, очень больших проблем (посмотрите страницу решателя нелинейной оптимизации IPOPT , чтобы понять, что я имею в виду)

4 голосов
/ 21 сентября 2010

2) Похоже, вы ищете Eigen .

3) Я полагаю, что если вы занимаетесь разреженной линейной алгеброй, то скорее раньше, чем позже вы захотите получить все ускорения, которые вы можете получить, поэтому я бы просто придерживался C ++. Я не вижу смысла в использовании Python для этого, если быстро не протестируем прототип, который вы уже сделали в C ++.

4 голосов
/ 21 сентября 2010

Как говорит llasram, многие библиотеки на python написаны на C / C ++, поэтому python должен работать с приемлемой скоростью.

На C ++ вы также можете протестировать gsl (научная библиотека gnu), но я считаю, что процедуры линейной алгебры будут такими же, как Boost (для этого две библиотеки используют BLAS). Для разреженной линейной алгебры вы должны взглянуть на SBLAS , но я никогда не использовал ее. Вот краткие общие "за и против", которые я вижу:

  • C ++:
    • Заставит вас сохранить хорошо структурированную программу
    • Может быть легко упакован для языков высокого уровня (например, python), чтобы обеспечить быстрое тестирование (посмотрите python c api или swig ) .
  • Python:
    • легко отлаживать, но может легко привести к плохо структурированным программам
    • может очень легко импортировать данные для тестов
    • есть несколько очень надежных библиотек, таких как scipy / numpy (кстати, scipy также использует BLAS для линейной алгебры)
    • управляемый код

Я лично использую gsl для манипулирования матрицами, и оборачиваю свои библиотеки C ++ в библиотеки Python, чтобы легко тестировать данные. На мой взгляд, это способ объединить плюсы двух языков.

2 голосов
/ 21 сентября 2010

У меня нет непосредственного опыта, но операции scipy / numpy почти все реализованы на C. Пока большая часть того, что вам нужно сделать, выражается в scipy / numpy функции, то ваш код не должен быть намного медленнее, чем эквивалентный C / C ++.

1 голос
/ 21 сентября 2010

Скорость сейчас больше не проблема для python, так как появились ctypes и cython. Что хорошего в cython, так это в том, что вы пишете код на python, и он генерирует код c, не требуя, чтобы вы знали одну строку c, а затем компилирует в библиотеку, или вы даже можете создать stanalone. Ctypes также похож, хотя и немного медленнее. Из проведенных мною тестов код Cython работает так же быстро, как и код c, и это имеет смысл, поскольку код cython переводится в код c. Ctypes немного медленнее.

Итак, в конце концов, это вопрос профилирования, посмотрите, что медленно в python, и переместите его на cython, или вы можете обернуть ваши существующие библиотеки c для python в cython. Это довольно легко достичь скорости c таким способом.

Поэтому я рекомендую не тратить усилия, которые вы вложили в создание этих библиотек c, обернуть их с помощью Cython, а все остальное - с помощью Python. Или вы можете сделать все это с помощью Cython, если хотите, так как Cython - это python bar с некоторыми ограничениями. И даже позволяет смешивать c-код. Таким образом, вы можете сделать часть этого в c и частично это python / cython. В зависимости от того, что заставляет вас чувствовать себя более комфортно.

Также можно использовать Numpy и SciPy, чтобы сэкономить больше времени и предоставить готовые решения ваших проблем / потребностей. Вам, безусловно, стоит их проверить. У Numpy даже есть инструмент для создания встроенного кода C внутри кода Python, точно так же, как вы можете встроить код сборки внутри кода C. Но я думаю, что вы бы предпочли использовать Cython. Помните, потому что cython - это и c, и python одновременно, он позволяет вам напрямую использовать библиотеки c и python.

...