Oam писал(а):
Уважаемый abc_qmost!
Судя по содержанию вашей интернет-страницы, вы - тот самый человек, которой сможет компетентно может ответить на три моих давно назревших вопроса:
1) Сильно ли ушли вперед АЛГОРИТМИЧЕСКИ процедуры нахождения всех собственных значений и векторов действительной симметричной матрицы малых порядков по сравнению со временами создания Справочника? Например, матрица с габаритами типа 64х64, по-видимому, не требующая никаких дополнительных операций для деления ее на блоки. Во сколько раз можно надеяться ускорить ее обработку по сравнению со старым алгоритмом из EISPACK (tred2+tql2)? Подчеркиваю, что вопрос касается именно алгоритмической сложности алгоритма (число умножений, делений, выборки), а отнюдь не реализаций алгоритма со всевозможными ухищрениями на разных Core Duo и им подобным.
2) По своему опыту знаю, насколько быстрее начинает работать алгоритм после замены С-ишной процедуры вычисления скалярного произведения на ассеблерную. Главную роль тут, конечно же, играет возможность использовать внутренний регистр процессора в качестве накопителя суммы, в то время как компилятор Си заставил бы на каждом обороте цикла дважды лазить в память, считывая и записывая текущее значение суммы. В связи с этим, у меня к вам вопрос, как к практику: во сколько раз быстрее удается организовать вычисления скалярного произведения двух массивов типа double при переходе на SSE2 и SSE3 инструкции? Нет ли у вас статистики такого рода? Конкретно меня интересует сравнение 3-х типов вычислений: а) накопление суммы в регистре FPP87, b) использование SSE2 и SSE3 (не помню сейчас, что появилось в SSE3 нового), и, наконец, c) SSE4 (где вроде бы появилась новая инструкция DPPD — Dot Product of Packed Double Precision Floating-Point Values).
3) И последний вопрос на эту тему. Известно, что суммирование больших и малых величин (а накопление скалярного произведения - как раз такой случай) является одной главных источников возникновения погрешностей. При вычислениях на FPP87 сумма может накапливается в его регистре, имеющим более длинную мантиссу, чем double (так называемый "long double" или TBYTE). Это позволяло в большинстве случаев иметь верным даже последний знак суммы после записи ее в double-элемент матрицы. А с переходом на SSE тип long double стали всячески избегать, исключив его даже из компиляторов (например, MS Studio 2005). Причина тут ясна - некратность длины этого типа степени числа 2, что не обеспечивает выравнивания. Однако как оцениваете именно вы такое обрезание мантиссы? Существенна ли эта потеря в деле матричных вычислений? Каково ваше мнение на этот счет?
Ответ на 1 вопрос:
Если оставить в стороне блочные методы, которые не имеет смысла применять для малых матриц, то сильно изменилась tql2, вернее та ее часть, которая отвечает за работу с трехдиагональной матрицей (и то недавно). Скорость этой части в некоторых случаях возрасла на 500%. Этот алгоритм реализован в пакете Intel MKL.
Ответ на 2 вопрос:
Я специально таких замеров не делал. С точки зрения SS2 меня интересовали BLAS LEVEL 2 для трехдиагонализации (умножение м-цы на вектор - увеличение скорости ~ в 2.5 раза) и BLAS LEVEL 3 (перемножение м-ц - увеличение скорости ~ в 8 раз). Но алгоритмы очень хитрые и не сводятся к простой реализации скалярного произведения.
Что касается SSE4, то ничего не могу сказать.
Ответ на 3 вопрос:
"long double" есть в Intel'овском C-ном трансляторе. Под него выделяется 16 байт.
Что касается полезности "long double", то он позволяет решать более сложные задачи, чем отмечено в Вашем 3-ем пункте.
Что касается MS Studio 2005, то для технологии NET "long double" как кость в горле.