2010-12-30 5 views
10

Potrzebuję wykonać mnożenie na macierzach. Szukam biblioteki, która może to zrobić szybko. Korzystam z kompilatora Visual C++ 2008 i mam rdzeń i7 860, więc jeśli biblioteka jest zoptymalizowana do mojej konfiguracji, jest idealna.Co to jest dobra biblioteka C++ do operacji macierzowych

+2

LAPACK + BLAS dostaje większość rzeczy zrobić –

Odpowiedz

5

Sprawdź w Eigen. Powinien mieć wszystko, czego potrzebujesz.

+0

Czy używać wątków (jeśli nie to nie jest szybki)? – Yttrill

+0

Eigen jest dobry tylko w małych matrycach. Nie używa wątków dla większych macierzy. Ale używa SSE2, gdy jest dostępny. –

+0

Cóż, ich własny benchmark pokazuje różne ... Heck, wątki mogą być zaimplementowane przez użytkownika poprzez tworzenie produktów blokowych, jeśli naprawdę tego potrzebujesz. – rubenvb

3

Mam dobre doświadczenia z Boost's uBLAS. To dobra opcja, jeśli korzystasz już z Boost.

+0

Czy używa wątków (jeśli nie, to nie jest szybkie)? – Yttrill

+2

Korzysta z dowolnej biblioteki BLAS zainstalowanej w systemie. Intel dostarcza taki, który używa wątków i instrukcji wektorowych: google dla Intel MKL. Nie jest to jednak darmowe. –

+0

Miałem naprawdę przerażające doświadczenie z uBLAS firmy Boost. Jest to całkowicie nieintuicyjne i trudne do wymyślenia. Na przykład, skąd mam wiedzieć, że mnożenie macierzy wektorowych odbywa się za pomocą 'prod()' - dlaczego nie operator '*'? Nie mogę nawet pomnożyć dwóch wektorów. –

1

Możesz użyć GNU Scientific Library(GSL).

Oto strona opisująca operacje macierzowe dostępne w bibliotece, w tym mnożenia (gsl_matrix_mul_elements()):

http://www.gnu.org/software/gsl/manual/html_node/Matrix-operations.html

A oto kilka linków na początek z użyciem GSL z visual studio:

http://gladman.plushost.co.uk/oldsite/computing/gnu_scientific_library.php

http://www.quantcode.com/modules/smartfaq/faq.php?faqid=33

+0

Naprawdę? Kompilacja kodu gnu w MSVC++? Chodzi mi o to, że jeśli naprawdę chcesz osiągnąć wydajność, użyjesz BLAS-a opartego na Atlasie, ale wątpię, czy byłoby to łatwe do zbudowania na Windowsie. :) – Yttrill

+0

http://math-atlas.sourceforge.net/errata.html# gccCrazy –

-1

Istnieje opcja samodzielnego zaimplementowania tego, być może przy użyciu std :: valarray, ponieważ może to być paralelizowane za pomocą OpenMP: gcc na pewno ma taką wersję, prawdopodobnie MSVC++ też.

W przeciwnym razie, następujące triki: jedna z matryc powinna zostać transponowana. Wtedy masz:

AB [i, j] = Sum (k) [j, k] B^t [j, k]

gdzie jesteś skanowanie pamięci ciągłej. Jeśli masz 8 rdzeni, możesz dość łatwo podzielić zestaw [i, j] indeksów na 8 i podać każdemu rdzeniu 1/8 całego zadania. Aby uczynić go jeszcze szybszym, można użyć instrukcji wektorowych mnożących się, większość kompilatorów zapewni w tym celu specjalną funkcję. Wynik nie będzie tak szybki, jak biblioteka, ale powinien być w porządku.

Jeśli robisz dłuższe obliczenia, takie jak ocena wielomianowa, oceniający wątek, który ma również obsługę wątków (gak, dwa rodzaje wątków), wykona dobrą robotę, nawet jeśli nie dostroi się na niskim poziomie. Jeśli naprawdę chcesz robić rzeczy szybko, musisz użyć odpowiednio dostrojonej biblioteki, takiej jak Atlas, ale wtedy prawdopodobnie nie uruchomisz Windows, jeśli poważnie myślisz o HPC.

+3

Nie należy samodzielnie wykonywać operacji macierzowych. Użyj implementacji BLAS. –

1

nie może ścigać się z bibliotek naukowych, ale z Visual C++ jest w zasięgu ręki

#include <windows.h> 
#include <gdiplus.h> 
#pragma comment (lib,"Gdiplus.lib") 
using namespace Gdiplus; 

int main() 
{ 
    ULONG_PTR gpToken = 0; 
    GdiplusStartup(&gpToken, &GdiplusStartupInput(), NULL); 
    //lib inited 

    Matrix A; 
    A.Translate(10,20); 

    Matrix B; 
    B.Rotate(35.0); 

    A.Multiply(&B); 
    if (A.IsInvertible()) 
     A.Invert(); 
    if (!A.IsIdentity()) 
     A.RotateAt(120.0, PointF(10,10)); 

    //getting values 
    REAL elements[6]; 
    A.GetElements(elements); 

    //lib stopped 
    GdiplusShutdown(gpToken); 
    return 0; 
} 

więc z tego można łatwo wziąć przeszkodę mnożenia macierzy (w systemie Windows)

GdiPlus Matrix Documentation

6

BLAS jest de facto standardem Fortran dla wszystkich podstawowych operacji algebry liniowej (w zasadzie multiplikacji macierzy i wektorów). Dostępne są liczne implementacje. Na przykład:

  • ATLAS jest darmowy i podobno samoptymalizujący się. Trzeba to jednak samemu skompilować.
  • Goto BLAS jest utrzymywany przez Kazushige Goto w TACC. Jest bardzo dobry w uzyskiwaniu ostatniej wydajności z nowoczesnych procesorów. Jest to jednak tylko do użytku akademickiego.
  • Intel MKL zapewnia zoptymalizowane BLAS dla procesorów Intela. To nie jest darmowe, nawet do użytku akademickiego.

Następnie można użyć opakowania C++, na przykład boost::ublas.

Jeśli programujesz na systemach rozproszonych, istnieją PBLAS i ScaLAPACK, które umożliwiają korzystanie z przekazywania komunikatów dla operacji algebry liniowej. Na maszynie wielordzeniowej, zwykle implementacje BLAS (przynajmniej Intel MKL) używają wątków dla wystarczająco dużych macierzy.

Jeśli chcesz bardziej zaawansowane procedury algebry liniowej (wartości własne, systemy liniowe, najmniejszy kwadrat, ...), to istnieje inny de facto standardowy LAPACK Fortran. Według mojej wiedzy, nie ma nic, co mogłoby go elegancko zintegrować z C++, poza wywołaniem pustych procedur Fortrana. Musisz napisać kilka wrapperów, aby ukryć wywołania Fortran i zapewnić implementację sprawdzania typu dźwięku.

7

FWIW, Eigen 3 używa wątków (OpenMP) dla produktów macierzowych (w odpowiedzi na powyższe stwierdzenie o Eigen nie używa wątków).