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

Что касается моего кода на C++, я задал этот вопрос около двух дней назад. Но теперь я понимаю, что мне нужно кодировать на Фортране, поскольку ядра, которые я пишу, будут частью существующего приложения, написанного на Фортране 77. Поэтому я снова задаю этот вопрос, на этот раз в контексте Фортрана. Спасибо.

У меня есть разные функции для умножения квадратных матриц в зависимости от размера матрицы, который варьируется от 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. Если вы не можете, попросите ваш компилятор выполнить встраивание между разными файлами.   -  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: на самом деле это трехмерные матрицы, представляющие тензоры. И хотя для своих экспериментов я установил максимальное значение 20x20x20, оно может быть больше, возможно, 40x40x40 и т. д. В любом случае, я видел улучшения, применяющие перестановку циклов и развертывание циклов даже для размеров 10x10x10. Спасибо.   -  person Tania    schedule 09.09.2015
comment
Поскольку больше нет такой вещи, как компилятор F77, а F77 на самом деле в основном является подмножеством более новых воплощений Fortran, вы можете просто использовать более новые конструкции в своем коде, не изменяя основное приложение.   -  person haraldkl    schedule 09.09.2015


Ответы (2)


Если matrixSize является константой времени компиляции в языковом смысле (т. е. это ПАРАМЕТР Fortran), то я ожидаю, что большинство оптимизирующих компиляторов воспользуются этим и полностью исключат ветвь времени выполнения.

Если matrixSize не является константой времени компиляции, то вы должны сделать ее таковой. Средства, предоставленные в более поздних версиях (модулях) языка Фортран, упрощают распространение такой константы времени выполнения из одной точки определения в точку использования.

Обратите внимание, что соответствие 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 приводит к сборке для соответствующей области, которая не ссылается ни на что, кроме процедуры, которая является целью соответствующего будет -always-be-selected, если ветвь в источнике. Даже если бы я понятия не имел, что означают различные мнемоники ассемблера (что почти так и есть!), это говорит мне о том, что компилятор устранил ветвь. Попробуйте со своим кодом. - 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 версий кода, по одной для каждого размера, и использовать их в наборе ifs. чтобы решить, что использовать.

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