Бенчмарки реализации матрицы, стоит ли хлестать себя?

Я пытаюсь найти в Интернете тесты умножения/инверсии матриц. Моя реализация C++ в настоящее время может инвертировать матрицу 100 x 100 за 38 секунд, но по сравнению с этот тест производительности, который я нашел, моя реализация производительности, которую я нашел, Я не знаю, является ли это чем-то сверхоптимизированным или действительно можно легко инвертировать матрицу 200 x 200 примерно за 0,11 секунды, поэтому я ищу дополнительные тесты для сравнения результатов. У тебя есть хорошая ссылка?

ОБНОВЛЕНИЕ Я обнаружил ошибку в своем коде умножения, которая не влияла на результат, но вызывала бесполезную трату цикла. Теперь моя инверсия выполняется за 20 секунд. Времени еще много, и любые идеи приветствуются.

Спасибо, ребята


person tunnuz    schedule 05.02.2009    source источник


Ответы (7)


Этот вид операции чрезвычайно чувствителен к кешу. Вы хотите выполнять большую часть своей работы с переменными, которые находятся в вашем кеше L1 и L2. Ознакомьтесь с разделом 6 этого документа:

http://people.redhat.com/drepper/cpumemory.pdf

Он проведет вас через оптимизацию матричного умножения с оптимизацией кеша и получит несколько значительных улучшений производительности.

person twk    schedule 05.02.2009

Проверьте, не передаете ли вы огромные матричные объекты по значению (поскольку это может быть дорогостоящим, если копировать всю матрицу).
Если возможно, передавайте по ссылке.

Дело в матрицах и C++ заключается в том, что вы хотите избежать копирования настолько, насколько это возможно.
Таким образом, ваш основной объект, вероятно, не должен содержать «данные матрицы», а должен содержать метаданные о матрице и указатель (обернутый чем-то smart) в часть данных. Таким образом, при копировании объекта вы копируете только небольшой фрагмент данных, а не все (см. пример реализации строки).

person Martin York    schedule 05.02.2009
comment
Я делаю именно так, как вы объяснили, мои матрицы содержат только метаданные (строки, столбцы, определитель) и общие указатели на содержимое. - person tunnuz; 05.02.2009

Зачем вообще нужно реализовывать собственную библиотеку матриц? Как вы уже обнаружили, уже существуют чрезвычайно эффективные библиотеки, делающие то же самое. И как бы людям ни хотелось думать о C++ как о языке производительности, это верно только в том случае, если вы действительно хорошо разбираетесь в этом языке. Очень легко написать ужасно медленный код на C++.

person jalf    schedule 05.02.2009
comment
Кажется, вы ограничиваете свои комментарии C++. Мне кажется, что на любом языке одинаково легко писать медленный код. - person Jon Trauntvein; 06.02.2009
comment
И да и нет. Конечно, можно писать медленный код на любом языке, но в C++ он используется по умолчанию, если вы точно не знаете, что делаете. Например, C# не вызывает десятки ненужных операций копирования и не наказывает вас за вызов new(). Это может быть очень дорого в С++. - person jalf; 06.02.2009
comment
Есть много, казалось бы, безобидных вещей, которые вы можете делать на C++, но которые, тем не менее, снижают производительность. Если взять что-то вроде Python или Java, производительность будет гораздо более простой и предсказуемой даже для неспециалистов. - person jalf; 06.02.2009

Я не знаю, является ли это чем-то сверхоптимизированным или действительно вы можете легко инвертировать матрицу 200 x 200 примерно за 0,11 секунды.

MATLAB делает это без особых усилий. Реализуете ли вы процедуры LAPACK для инверсии матриц (например, разложения LU)?

person Zach Scrivena    schedule 05.02.2009
comment
Я делаю это с LUP-факторизацией. - person tunnuz; 05.02.2009
comment
@tunnuz: Еще одна причина несоответствия скорости заключается в том, что многие оптимизированные реализации написаны с учетом определенных наборов инструкций (например, библиотека Intel Math Kernel Library). Многие из них также изменены на уровне сборки для повышения производительности. - person Zach Scrivena; 05.02.2009

Пробовали профилировать?

После этого документа (pdf) расчет для 100 x 100 матрице с LU-разложением потребуется 1348250 (операций с плавающей запятой). Ядро 2 может выполнять около 20 Гфлопс (показатели процессора) . Так что теоретически вы можете сделать инверсию за 1 мс.

Без кода довольно сложно утверждать, в чем причина большого разрыва. Из моего опыта использования микрооптимизации, такой как развертывание цикла, кэширование значений, SEE, многопоточность и т. д., вы получите только ускорение, которое в лучшем случае является лишь постоянным фактором вашего тока (которого может быть достаточно для вас).

Но если вы хотите увеличить скорость на порядок, вам следует взглянуть на свой алгоритм, возможно, в вашей реализации декомпозиции LU есть ошибка. Еще одно место, на которое стоит обратить внимание, — это организация ваших данных, попробуйте другую организацию, объедините элементы строки/столбца.

person Ismael    schedule 06.02.2009

Тесты LINPACK основаны на решении задач линейной алгебры. Они доступны для разных компьютеров и языков. Может быть, они смогут помочь и вам.

Библиотеки LINPACK C++ также доступны здесь.

person duffymo    schedule 05.02.2009
comment
Библиотеки LINPACK C++ доступны здесь: people.sc.fsu.edu/~ burkardt/cpp_src/linpack/linpack.html - person duffymo; 05.02.2009

На самом деле я выиграл около 7 секунд, используя **double**s вместо **long double**s, но это не так уж и много, так как я потерял половину своей точности.

person tunnuz    schedule 05.02.2009
comment
Вы уверены, что? По моему опыту, вы не получаете почти вдвое большей точности с long double. См. stackoverflow.com/questions/476212/ для получения подробной информации. - person Bill the Lizard; 05.02.2009
comment
Что ничего не говорит о точности, которую вы получите в конце большого количества вычислений. В данном приложении с интенсивными вычислениями он может потерять половину своей точности. - person David Thornley; 05.02.2009
comment
Нет, на самом деле это была оценка, основанная на количестве битов на число. - person tunnuz; 05.02.2009
comment
Это странно, FPU должен выполнять все свои вычисления в 80 битах, что соответствует размеру длинного двойного числа. (если вы не компилируете для x64) - person Ismael; 06.02.2009