Оптимизиране на оператора if-then-else във Fortran 77

За моя C++ код зададох този въпрос преди около два дни. Но сега осъзнавам, че трябва да направя кодирането на Fortran, тъй като ядрата, които пиша, ще бъдат част от съществуващо приложение, написано на Fortran 77. Затова публикувам този въпрос отново, този път контекстът е Fortran. Благодаря ти.

Имам различни функции за умножение на квадратна матрица в зависимост от размера на матрицата, който варира от 8x8 до 20x20. Функциите се различават една от друга, защото всяка използва различни стратегии за оптимизация, а именно различни пермутации на цикъла и различни фактори за разгъване на цикъла. Размерът на матрицата е неизменен по време на живота на програмата и е известен по време на компилиране. Целта ми е да намаля времето за вземане на решение коя функция трябва да се използва. Например, наивна реализация е:

if (matrixSize == 8) C = mxm8(A, B);
else if (matrixSize == 9) C = mxm9(A,B);
 ...
else if (matrixSize == 20) C = mxm20(A,B);

Времето, необходимо за решаване коя функция да се използва за всяко умножение на матрица, е нетривиално в този случай, особено след като умножението на матрица се случва често в кода. Благодаря предварително за всяко предложение как да се справя с това във Fortran 77.


person Tania    schedule 08.09.2015    source източник
comment
Защо трябва да е F77? Можете да използвате избран случай или указател на функция, за да разрешите това, не мисля, че те биха били по-бавни.   -  person haraldkl    schedule 09.09.2015
comment
Времето, необходимо за оператора if, трябва да е незначително в сравнение с умножението на матрицата. Най-доброто, което можете да направите, е да поставите функциите mxm в един и същи файл, така че компилаторът в крайна сметка да може да вгради функцията mxm. Ако не можете, помолете вашия компилатор да направи вграждане между различни fies.   -  person Anthony Scemama    schedule 09.09.2015
comment
Виждам, че вече има приет отговор, но се чудя дали за този размер на матриците (максимум 20x20) си струва работата. Тези матрици ще се поберат в кеша на почти всеки съвременен компютър, което го прави почти нечувствителен към оптимизацията. Случайно да сте виждали някаква разлика между вашите версии на алгоритми?   -  person innoSPG    schedule 09.09.2015
comment
@haraldkl: Трябва да е F77, тъй като основното приложение е F77 и нямам власт да променя това.   -  person Tania    schedule 09.09.2015
comment
@AnthonyScemama: Благодаря за приноса.   -  person Tania    schedule 09.09.2015
comment
@innoSPG: Това всъщност са 3D матрици, представителни за тензори. И въпреки че за моите експерименти го зададох на максимум 20x20x20, той може да бъде по-голям от това, може би 40x40x40 и т.н. Както и да е, виждал съм подобрения, прилагащи пермутация на цикъл и разгъване на цикъл дори за размери 10x10x10. Благодаря.   -  person Tania    schedule 09.09.2015
comment
Тъй като вече няма такова нещо като F77 компилатор и F77 всъщност е предимно подмножество на по-новите въплъщения на Fortran, можете просто да използвате по-нови конструкции в кода си, без да променяте основното приложение.   -  person haraldkl    schedule 09.09.2015


Отговори (2)


Ако matrixSize е времева константа за компилиране в езиков смисъл (т.е. това е Fortran ПАРАМЕТЪР), тогава бих очаквал повечето оптимизиращи компилатори да се възползват от това и напълно да елиминират клон по време на изпълнение.

Ако matrixSize не е константа за време на компилиране, тогава трябва да я направите такава. Удобствата, предоставени в по-късните ревизии (модули) на езика Fortran, правят много лесно разпространението на такава константа по време на изпълнение от една точка на дефиниране до точка на използване.

Обърнете внимание, че съответствието с Fortran 77 също отговаря на Fortran 90 и с много малки изключения ще съответства и на Fortran 2015.

person IanH    schedule 08.09.2015
comment
matrixSize наистина е ПАРАМЕТЪР на Fortran. Когато отстранявам грешки в моя изпълним файл, установявам, че изразите if се оценяват. - person Tania; 09.09.2015
comment
Ако можете да разберете отстраняването на грешки във вашия изпълним файл, тогава не сте активирали нищо подобно на пълната способност за оптимизиране на компилаторите или използвате компилатор с невероятно слаба оптимизация. - person IanH; 09.09.2015
comment
Използвах gfortran -g, но има ли начин да знам със сигурност, че клонът се елиминира, може би без да прочетем съответното събрание? - person Tania; 09.09.2015
comment
Прост тест тук (очевидно нямам представа какъв е вашият действителен код на Fortran...) с gfortran -g -S води до асемблиране за съответния обхват, който не препраща към нищо освен процедурата, която е целта на съответната воля -винаги да бъде избран, ако клонът е в източника. Дори и да нямах представа какво означават различните мнемоники на асемблера (което до голяма степен е така!), това ми казва, че компилаторът е премахнал разклонението. Опитайте с вашия собствен код. - person IanH; 09.09.2015
comment
Исках да потвърдя, че това наистина е така. Само съответната функция завършва в сборката. Благодаря много. - person Tania; 09.09.2015
comment
Ако това е константа по време на компилиране, просто използвайте препроцесора вместо Fortran, за да направите разклонението. - person Jeff Hammond; 09.09.2015
comment
@Jeff Използването на препроцесора би било ретроградно. Той не предлага никаква полза (производствените компилатори ще направят необходимата оптимизация), но идва с непренебрежимо преносимост и разходи за сложност. - person IanH; 09.09.2015
comment
@IanH Моля, назовете Fortran компилатор, който не може да обработва предварително оператори if-elif-else-endif. - person Jeff Hammond; 09.09.2015
comment
Някои издания на LF95 са търговски примери. Доста помощни програми за изходен код също няма да обработват директивите на предпроцесора извън кутията. Предварителната обработка винаги може да бъде осигурена от външен инструмент, но това е цена на сложността, в допълнение към типичните проблеми със сложността на източника, които носи използването на предварителна обработка, която основно не познава езика. Използването на препроцесора е необходимо зло в някои ситуации, но това не е една от тях. - person IanH; 09.09.2015

Ако е известно по време на компилиране, тогава имате нужда само от 1 версия на тази функция. Изглежда, че просто поставяте всяка версия на функцията в нейния obj обектен файл или библиотека и след това се свързвате към подходящата.

Ако сте искали да кажете, че той е известен по време на изпълнение, но не се променя по време на курса или изпълнението, тогава можете да имате 13 версии на кода, по една за всеки размер, и да използвате набор от if да реши кое да използва.

person Scott Hunter    schedule 08.09.2015
comment
Няма ли да е проблем с опцията за време за свързване към съответния обектен файл, че функциите във всеки обектен файл трябва да имат едно и също име, да речем mxm, за да бъдат правилно посочени от кода? - person Tania; 09.09.2015