![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
uBLAS OverviewBoost , ,
|
Description | Operator |
---|---|
Индексирование векторов и матриц | vector::operator(size_t i); |
Распределение векторов и матриц | vector::operator = (const вектор_expression &); |
Неарочные операции на векторах и матрицах | vector_expression оператор - (const вектор_expression &); |
Бинарные операции на векторах и матрицах | vector_expression оператор + (const вектор_expression & , const вектор_expression & ); |
Умножение векторов и матриц скаляром | vector_expressionоператор * (const scalar_expression & , const вектор_expression & ); |
Мы решили не использовать перегрузку оператора для следующих других примитивных:
Description | Function |
---|---|
Левое умножение векторов с матрицей | vector_expression prod< vector_type > (const matrix_expression &, const вектор_expression &); |
Правильное умножение векторов с матрицей | vector_expression prod< vector_type > (const вектор_expression &, const matrix_expression &); |
Умножение матриц | matrix_expression prod< matrix_type > (const matrix_expression &, const matrix_expression &); |
Внутренний продукт векторов | scalar_expression internal_prod (const вектор_expression &, const вектор_expression &); |
Внешний продукт векторов | matrix_expression outer_prod (const вектор_expression &, const вектор_expression &); |
Перевод матрицы | matrix_expression trans (const matrix_expression &); |
Для достижения цели эффективности численных вычислений необходимо преодолеть две трудности в формулировании абстракций с C++, а именно временные и виртуальные функциональные вызовы. Шаблоны экспрессии решают эти проблемы, но, как правило, замедляют время компиляции.
Абстрактные формулы на векторах и матрицах обычно составляют пару неарочных и бинарных операций. Обычный способ оценки такой формулы состоит прежде всего в том, чтобы оценить каждую операцию листьев композиции на временный и следующий, чтобы оценить композит, приводящий к другому временному. Этот метод стоит дорого с точки зрения времени, особенно для малых и космических особенно для больших векторов и матриц. Подход к решению этой проблемы заключается в использовании ленивой оценки, как известно из современных функциональных языков программирования. Принцип этого подхода состоит в том, чтобы оценить сложный элемент выражения и назначить его непосредственно цели.
Два интересных и опасных результата:
Можно получить серьезные побочные эффекты, используя элемент мудрой оценки на векторах или матрицах. Рассмотрим матрицу векторного продукта x = A x. Оценка A1x и присвоение x1 меняет правую сторону, так что оценка A2xx возвращает неправильный результат. В этом случае есть aliases элементов xn как на левой, так и на правой стороне задания.
Наше решение этой проблемы состоит в том, чтобы оценить правую сторону уступки во временной, а затем назначить эту временную на левую сторону. Чтобы позволить дальнейшую оптимизацию, мы обеспечиваем соответствующую функцию члена для каждого оператора уступки, а также noalias
синтаксис. Используя этот синтаксис, программист может подтвердить, что левая и правая стороны задания независимы, так что элемент мудрой оценки и прямого назначения цели является безопасным.
Вычисленная сложность может быть неожиданно большой при определенных сирумстанциях. Рассмотрим цепный векторный продукт A (B x). Обычная оценка A (B x) является квадратичной. Опущенная оценка B xi линейна. Поскольку каждый элемент B xi необходим линейно в зависимости от размера, полностью отложенная оценка цепного векторного продукта матрицы A (B x) является кубическим. В таких случаях нужно повторно вводить temporaries в выражение.
Оценка ленивого выражения обычно приводит к определению классовой иерархии терминов. Это приводит к использованию динамического полиморфизма для доступа к отдельным элементам векторов и матриц, которые также известны как дорогие с точки зрения времени. Решение было найдено пару лет назад самостоятельно Дэвидом Вандервордом и Тоддом Велдхуйзеном и обычно называется шаблонами выражения. Шаблоны экспрессии содержат ленивую оценку и заменяют динамический полиморфизм статическим, т.е. компиляционным полиморфизмом во времени. Шаблоны экспрессии в значительной степени зависят от известного трюка Бартона-Нэкмана, также придуманного Джимом Коплином «критически определенных рекурсивных шаблонов».
Шаблоны выражения формируют основу нашей реализации.
Это также хорошо известный факт, что шаблоны выражения бросают вызов существующим компиляторам. Мы смогли значительно уменьшить количество необходимых шаблонов выражения, используя трюк Бартон-Накман.
Мы также решили поддержать двойное обычное осуществление (т.е. не используя шаблоны выражения) с обширными границами и проверкой типа операций вектора и матрицы для поддержки цикла разработки. Переход от режима отладки к режиму выпуска контролируется NDEBUG
предпроцессорный символ
.
Каждая библиотека C++, поддерживающая линейную алгебру, будет измерена против давнего пакета Fortran BLAS. Теперь мы описываем, как звонки BLAS могут быть отображены на наших классах.
Страница Обзор операций Матрицы и Вектора дает краткое резюме наиболее используемых операций на векторах и матрицах.
BLAS Call | Mapped Library Expression | Mathematical Description | Comment |
---|---|---|---|
сум или дасум |
norm_1 (x) |
сум |xi| | Вычисляет l1 (сумма) норму реального вектора. |
scasum ИЛИ dzasum |
реальный (сум (v)) + imag (сумма (v))) |
(xi) + sum im(xi) | Вычисляет сумму элементов сложного вектора. |
_nrm2 |
norm_2 (x) |
sqrt (сумма |xi|2 ) | Вычисляет l2 (евклидовая) норма вектора. |
i_amax |
norm_inf (x) |
макс |xi| | linf (максимальная) норма вектора. BLAS вычисляет индекс первого элемента, имеющего это значение. |
_dot |
inner_prod (x, y) или
|
xT y или xH y |
Вычисляет внутренний продукт двух векторов. BLAS реализует определенную петлю unrollment. |
dsdot |
a + prec_inner_prod (x, y) |
a + xT y | Вычисляет внутренний продукт в двойной точности. |
_копия |
x = y |
x <- y | Копирует один вектор к другому. BLAS реализует определенную петлю unrollment. |
_swap |
swap (x, y) |
x <-> y | Плавает два вектора. BLAS реализует определенную петлю unrollment. |
_scal |
x *= a |
x <- x | Масштабирует вектор. BLAS реализует определенную петлю unrollment. |
_axpy |
y += a * x |
y <- x + y | Добавляет масштабированный вектор. BLAS реализует определенную петлю unrollment. |
_rot |
t.assign (a * x + b * y), |
(x, y) <- (a x + b y, -b x + a y) | Применяет вращение самолета. |
_rotg |
(a, b) <- (? a / sqrt (a2 + b2), ? b/ sqrt (a2 + b>2>) или (1, 00) |
Построит вращение самолета. |
BLAS Call | Mapped Library Expression | Mathematical Description | Comment |
---|---|---|---|
_t_mv |
x = prod (A, x) или или
|
x <- A x или x <- AT x или x <- AH x |
Вычисляет продукт матрицы с вектором. |
_t_sv |
y = решать (A, x, тег) илиinplace_solve (A, x, тег) илиy = реферат (A), x, тег) илиinplace_solve (A), x, тег) илиy = решать (герм (A), x, тег) илиinplace_solve (герм (A), x, тег) |
>>-11> > >> > > > >>> >>>> >>>>>> >>>> >>> >> >>> >>>>> >>>>> >>>>>>>> >>>>>>>>>>> >>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>>>> | Пополняет систему линейных уравнений с треугольной формой, т.е. A является треугольной. |
_g_mv |
y = a * prod (A, x) + b * y или или
|
y <- a x + b y или y <- aT x + b y y < - AH x + b y |
Добавляет масштабированный продукт матрицы с вектором. |
_g_r |
A += a * External_prod (x, y) или
|
A <- x yT + A или A <- x yH + A |
Выполняет рейтинг 1 обновление. |
_s_r |
A += a * External_prod (x, x) или
|
A <- x xT + A или A <- xH + A |
Выполняет симметричный или геммицианский ранг 1 обновление. |
_s_r2 |
A += a * External_prod (x, y) + или
|
A <- x yTT + a xTT + A или A <- x yH + a- y xH + |
Выполняет симметричный или геммицианский ранг 2 обновление. |
BLAS Call | Mapped Library Expression | Mathematical Description | Comment |
---|---|---|---|
_t_mm |
B = a * prod (A, B) илиB = a * prod (trans (A), B) илиB = a * prod (A, trans (B) или B = a * prod (trans (A), trans (B) или b = a |
B < - op (A) op (B) с op (X) = X или op (X) = XT или op (X) = XH |
Вычисляет масштабированный продукт из двух матриц. |
_t_sm |
С = решение (A, B, тег) илиinplace_solve (A, B, тег) илиC = решать (транс (A), B, тег) или или или
|
С <- A-1>-1>-11>1>> 1>> 1>> 1>> 2>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> | Пополняет систему линейных уравнений с треугольной формой, т.е. A является треугольной. |
_g_mm |
C = a * prod (A, B) + b * C или C = a * prod (A), B + b * C или C = a * b) + b * C или C = a |
C < - op (A) op (B) + b C с op (X) = X или op (X) = XT или op (X) = XH |
Добавляет масштабированный продукт из двух матриц. |
_s_rk |
B = a * prod (A, trans (A)) + b * B или B = a * prod (trans (A), A) + b * B или B = a * prod (A, herm (A) + b * B или B = a * prod (herm (A), A) + b |
B <- a AT + b или B <- aT A + b или B <- a A>H + b или B < - AH b> |
Выполняет симметричный или геммицианский ранг k обновление. |
_s_r2k |
C = a * prod (A, trans (B)) + или C = a * prod (A), B) + или C = a * prod (A, herm (B) +nbsp; prod) |
> > > > > > >> > > < > > > > < | Выполняет симметричный или геммицианский ранг 2 k обновление. |
uBLAS поддерживает множество различных схем хранения. Полные детали можно найти на Обзор Типов. Большинство типов, таких как vector< double>
и matrix< double>
, по умолчанию совместимы с C-решениями, но также могут быть настроены на включение совместимых данных FORTAN.
По причинам совместимости мы предоставляем массив, такой как индексирование векторов и матриц. Для некоторых типов (гермитианский, скудный и т.д.) это может быть дорогим для матриц из-за необходимых временных прокси-объектов.
uBLAS использует совместимые с STL распределители для распределения хранилища, необходимого для его контейнеров.
Нижеследующие таблицы содержат результаты одного из наших критериев. Этот ориентир сравнивает аборигенную реализацию C ('C mass') и некоторые библиотечные реализации. Безопасные варианты на основе библиотеки предполагают псевдоним, быстрые варианты не используют temporaries и функционально эквивалентны местной реализации C. Помимо общих классов вектора и матрицы, эталон использует специальные классы c_vector
и c_matrix
, которые предназначены для того, чтобы избежать каждого накладного через генеричность.
Базовая программа bench1 была составлена с GCC 4.0 и запущена на Athlon 64 3000+. Времена - это шкалы для разумной точности при запуске bench1 100.
Сначала мы комментируем результаты для двойных векторов и матриц измерения 3 и 3 x 3 соответственно.
Comment | ||||
---|---|---|---|---|
inner_prod | C-образец | 0.61 | 782 | Some abstraction penalty |
c_vector | 0.86 | 554 | ||
вектор |
1.02 | 467 | ||
vector + vector | C-образец | 0.51 | 1122 | Abstraction penalty: factor 2 |
c_vector | 1.17 | 489 | ||
вектор |
1.32 | 433 | ||
c_vector | 2.02 | 283 | ||
вектор |
6.95 | 82 | ||
outer_prod | C-образец | 0.59 | 872 | Some abstraction penalty |
c_matrix, c_vector | 0.88 | 585 | ||
матрица |
0.90 | 572 | ||
c_matrix, c_vector safe | 1.66 | 310 | ||
matrix |
2.95 | 175 | ||
prod (matrix, vector) | C-образец | 0.64 | 671 | No significant abstraction penalty |
c_matrix, c_vector | 0.70 | 613 | ||
матрица |
0.79 | 543 | ||
c_matrix, c_vector safe | 0.95 | 452 | ||
matrix |
2.61 | 164 | ||
matrix + matrix | C-образец | 0.75 | 686 | No significant abstraction penalty |
c_matrix | 0.99 | 520 | ||
matrix |
1.29 | 399 | ||
c_matrix сейф | 1.7 | 303 | ||
matrix |
3.14 | 164 | ||
prod (matrix, matrix) | C-образец | 0.94 | 457 | No significant abstraction penalty |
c_matrix | 1.17 | 367 | ||
matrix |
1.34 | 320 | ||
c_matrix сейф | 1.56 | 275 | ||
matrix |
2.06 | 208 |
Мы замечаем двухкратную потерю производительности для небольших векторов и матриц: сначала общее наказание за абстракцию для использования классов, а затем небольшие потери при использовании общих векторных и матричных классов. Различия в псевдонимах также значительны.
Далее мы комментируем результаты для двойных векторов и матриц измерения 100 и 100 x 100 соответственно.
Operation | Implementation | Elapsed [s] | MFLOP/s | Comment |
---|---|---|---|---|
inner_prod | C-образец | 0.64 | 889 | No significant abstraction penalty |
c_vector | 0.66 | 862 | ||
вектор |
0.66 | 862 | ||
vector + vector | C-образец | 0.64 | 894 | No significant abstraction penalty |
c_vector | 0.66 | 867 | ||
вектор |
0.66 | 867 | ||
c_vector | 1.14 | 501 | ||
вектор |
1.23 | 465 | ||
outer_prod | C-образец | 0.50 | 1144 | No significant abstraction penalty |
c_matrix, c_vector | 0.71 | 806 | ||
матрица |
0.57 | 1004 | ||
c_matrix, c_vector safe | 1.91 | 300 | ||
matrix |
0.89 | 643 | ||
prod (matrix, vector) | C-образец | 0.65 | 876 | No significant abstraction penalty |
c_matrix, c_vector | 0.65 | 876 | ||
матрица |
0.66 | 863 | ||
c_matrix, c_vector safe | 0.66 | 863 | ||
matrix |
0.66 | 863 | ||
matrix + matrix | C-образец | 0.96 | 596 | No significant abstraction penalty |
c_matrix | 1.21 | 473 | ||
matrix |
1.00 | 572 | ||
c_matrix сейф | 2.44 | 235 | ||
matrix |
1.30 | 440 | ||
prod (matrix, matrix) | C-образец | 0.70 | 813 | No significant abstraction penalty |
c_matrix | 0.73 | 780 | ||
matrix |
0.76 | 749 | ||
c_matrix сейф | 0.75 | 759 | ||
matrix |
0.76 | 749 |
Для более крупных векторов и матриц общее наказание за абстракцию для использования классов, по-видимому, уменьшается, небольшие потери при использовании общих векторных и матричных классов, похоже, остаются. Различия в псевдонимах также остаются видимыми.
Copyright (©) 2000-2002 Joerg Walter, Mathias Koch
Использование, модификация и распространение подлежат лицензии Boost Software, Version 1.0. (См. сопроводительный файл LICENSE_1_0.txt или копия на http://www.boost.org/LICENSE_1_0.txt ).
Статья uBLAS Overview раздела может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
:: Главная :: ::
реклама |