Шляхі акселерацыі выканання вылічальнай нагрузкі на Python
Антон Літвіненка, Кіеўскі нацыянальны ўніверсітэт імя Тараса Шаўчэнкі
LVEE 2011
Interpreted programming languages are known for their flexibility and convenience, but suffer from low execution speed comparing to compiled ones. However, they find a use for time-consuming applications. The enhanced methods of acceleration for interpreted languages are available, first of all just-in-time (JIT) compilation. The effect of the JIT compilation on the execution speed of a time-consuming scientific program is reported, and a few implementations of JIT compilers for Python are compared. PyPy was found to be the fastest one, Psyco — slightly slower, Unladen Swallow — nearly useless.
Інтэрпрэтаваныя мовы праграмавання ўсё часцей ужываюцца пры напісанні праграм для разнастайных сфераў дастасавання, у тым ліку такіх, што традыцыйна не асацыююцца з інтэрпрэтаванымі мовамі, а менавіта – напісанне праграм, якія патрабуюць вялікіх вылічальных рэсурсаў.
Так, напрыклад, існуе часткова напісаная на Python бібліятэка для квантавахімічнага мадэлявання pDynamo 1, аўтары якой адмовіліся ад традыцыйнага ў гэтай галіне выбару між Fortran, C або C++ і сваіх ранейшых напрацовак на Fortran, і аддалі перавагу інтэрфейсу на Python (з рэалізацыяй найбольш крытычнай да хуткасці часткі коду на C). Прычыны поспехаў інтэрпрэтаваных моў у гэтай галіне ў выпадку навуковых праграм, верагодна, абумоўленыя лёгкасцю распрацоўкі для неадмыслоўцаў.
Таксама гэтыя мовы зручнейшыя для распрацоўкі з элементамі рэфлектыўнага праграмавання (калі праграме неабходна генераваць частку ўласнага коду).
Аўтарам дакладу была распрацаваная праграма Mjöllnir, якая выконвае інтэрпрэтацыю вынікаў магнетахімічнага эксперыменту з выкарыстаннем паўнаматрычнага метаду рашэння аператарных ураўненняў для спін-гамільтаніяна магнітных узаемадзеянняў, зыходзячы з мадэлі, якая задаецца карыстальнікам 2. Для рашэння гэтае задачы неабходна на падставе мадэлі пабудаваць матрыцы спін-гамільтаніяна (прыклад на рыс.1), прычым у алгебраічным (сімвальным) выглядзе. Алгарытм пабудовы быў рэалізаваны на Python. Праграму можна атрымаць ад аўтара пад умовамі ліцэнзіі GNU GPL v3.
Безумоўна, праблема хуткасці выканання ў такім выпадку становіцца актуальнай.
Рыс.1: Матрыца спін-гамільтаніяна для асі z для комплексу Cu2
Метады акселерацыі выканання прадугледжваюць адыход ад чыстай інтэрпрэтацыі зыходнага коду ў момант выканання і пераход да разнастайных гібрыдных схемаў трансляцыі.
Па-першае, самая крытычная да рэсурсаў частка функцыянальнасці можа быць напісаная на кампіляванай мове праграмавання. Але такі падыход патрабуе перапісвання коду і можа ўскладняць рэалізацыю.
Ускосным дастасаваннем такога падыходу з’яўляецца выкарыстанне адных канструкцый мовы замест іншых, аналагічных, але хутчэйшых 3. Так, сапраўды, інструкцыя:
map(operator.add, l1, l2)
хутчэй, чым: map(lambda x,y: x+y, l1, l2). А спроба сабраць матрыцу ў адзін радок інструкцыяй collect_str+=a[i][j] у цыкле істотна прайграе інструкцыі:
"".join(map(lambda x:"".join(x),a)).
У той жа час, неабходна дакладна ведаць спосабы рэалізацыі інструкцый (якія могуць змяняцца з часам і залежаць ад рэалізацыі).
Прэкампіляцыя ў байт-код з’яўляецца традыцыйнай і выкарыстоўваецца заўсёды, калі ёсць такая мажлівасць.
Існуюць праекты статычных кампілятараў падмноства мовы Python у машынны код, напрыклад, Shedskin. Праект PyPy, акрамя іншых дастасаванняў, здольны статычна кампіляваць г.зв. падмноства RPython. На жаль, гэты падыход абмяжоўвае мажлівасці мовы (у прыватнасці, яго складана ўжыць для ўжо гатовага коду).
Найбольш цікавымі з’яўляюцца праекты JIT-кампілятараў:
- Модуль Psyco. Рэалізаваны як модуль CPython (стандартнае рэалізацыі мовы). З’яўляецца найбольш старым, вядомым, зручным, а да апошняга часу — і самым хуткім. Недахопы: прывязаны да версіі інтэрпрэтатара і платформы (толькі x86), прычым распрацоўка новых версій ускладненая (напрыклад, версіі пад Python 2.7 няма дагэтуль).
- Праект PyPy. Iнтэпрэтатар і JIT-кампілятар. Хуткасць выканання расце ад версіі да версіі і ўжо перавышае хуткасць Psyco 4. Ускладненая праца з вонкавымі бібліятэкамі на C.
- Праект Unladen Swallow. Пазіцыянуецца як аптымізаваны CPython з JIT-кампіляцыяй. Пакуль што працуе нашмат павольней за папярэднія два.
Агульная праблема ўсіх JIT-рэалізацый – патрабаванне большага аб’ёму памяці, чым CPython. Вынікі сінтэтычных тэстаў хуткасці наяўныя ў Сеціве 4. Для праверкі эфекту акселерацыі ў выпадку праграмы Mjöllnir былі выкананыя тэсты для біядзернага комплексу медзі (Cu2, 4 базісныя функцыі), трыядзернага Fe2Co (432) і 4-ядзернага Mn4 (625). Усярэдненыя вынікі для 10 запускаў (Core 2 Duo 2.4 GHz, Linux Fedora 12) прадстаўленыя на рыс.2 і ў табл., давяральныя інтэрвалы былі разлічаныя паводле размеркавання Ст’юдэнта.
Рыс.2: Дыяграма параўнання адносных часоў выканання праграмы Mjöllnir з рознымі JIT-кампілятарамі (значэнні нармаваныя на час самага павольнага выканання для мадэлі (у дужках, сек)).
Такім чынам, для праграмы Mjöllnir найбольш эфектыўным акселератарам выканання на дадзены момант з’яўляецца PyPy, і з улікам імклівага развіцця праекта верагодным ёсць ягонае выкарыстанне ў будучыні як асноўнага (цяпер ужываецца Psyco). Psyco дае блізкія вынікі, Unladen Swallow з’яўляецца неэфектыўным. Неадпаведнасць вынікаў для малой мадэлі (Cu2), верагодна, абумоўленая выдаткамі часу на JIT-кампіляцыю, якія не кампенсуюцца праз вельмі малы аб’ём разлікаў.
Табл.: Час выканання праграмы Mjöllnir, сек
Аўтар дзякуе С.А. Літвіненку за каштоўныя парады пры выкананні гэтае работы.
Лiтаратура
1 M.J. Field. The pDynamo Library for Molecular Simulations using Hybrid Quantum Mechanical and Molecular Mechanical Potentials, J. Chem. Theo. Comp., 4, 2008, 1151-1161.
2 А.С. Литвиненко, Е.А. Михалева, С.В. Колотилов, В.В. Павлищук. Влияние спин-орбитального взаимодействия на магнитную восприимчивость полиядерных комплексов 3d-металлов, содержащих ион Co2+, Теорет. и эксперим. химия, 2010, т. 46, с. 403-409.
3 Сказ о летающем змее. Агрессивная оптимизация программ на Python’e, http://www.xakep.ru/magazine/xa/123/102/1.asp
4 PyPy Speed Center: Comparison, http://speed.pypy.org/comparison