[C++] Behöver hjälp med matriser!

Permalänk
Medlem

[C++] Behöver hjälp med matriser!

Hej!

Jag skulle behöva multiplicera två matriser tillsammans (vi kan kalla dem A och B). Problemet är att jag inte riktigt vet hur jag ska göra detta i just C++.

En tanke var att använda sig av vektorer på följande sätt:

using namespace std; vector<vector<double> > A; vector<vector<double> > B;

Dock går det inte att multiplicera dessa direkt utan man får multiplicera vektorerna i vektorerna (d.v.s rad A1 * kolumn B1 osv) var för sig. Ett annat alternativ är att använda sig av arrays innehållande doubles, t.ex. på följande sätt:

double A[rowA][colA]; double B[rowB][colB];

med rowA, colA, rowB och colB redan specificerat tidigare. Samtidigt känns detta sätt ganska ineffektivt jämfört mot vektormultiplikation.

Vad rekommenderar ni?

Visa signatur

12c/24t 4.0GHz (Zen2) • 2x16GiB 3200MHz C14 • RTX 2080 FE 1965MHz 7000MHz • X570 I PW • Ghost S1 MKII

Permalänk
Datavetare

Varför inte använda något existerande bibliotek för detta? Då är problemet med att korrekt hantera matrisoperationer redan löst och som bonus får då även SSE/AVX-optimeringar.

Några exempel

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Medlem
Skrivet av Yoshman:

Varför inte använda något existerande bibliotek för detta? Då är problemet med att korrekt hantera matrisoperationer redan löst och som bonus får då även SSE/AVX-optimeringar.

Några exempel

Dessa bibliotek är självklart ett alternativ, men jag borde ha nämnt i mitt första inlägg att jag sitter och experimenterar med matriser i C++ från scratch! Mitt slutliga mål är att skriva en kod som kan hantera detta ungefär som dessa bibiliotek ovan, men jag är just nu i första stadier där jag funderar ut hur man kan multiplicera två matriser på ett så effektivt sätt som möjligt

Visa signatur

12c/24t 4.0GHz (Zen2) • 2x16GiB 3200MHz C14 • RTX 2080 FE 1965MHz 7000MHz • X570 I PW • Ghost S1 MKII

Permalänk
Datavetare

Tja det effektiva sättet att göra det är att endera använda ovan nämnda bibliotek, direkt använda SSE/AVX instrincts (inte att rekommendera) eller utnyttja någon teknik som "Cilk+ array notation".

Vill du göra det "för hand" med standard C++ är artikeln för Cilk+ ändå en bra referens då man visar logisk ekvivalent C++. Fördelen med Cilk+ metoden är dels att den är kompaktare och dels att den gör det möjligt för kompilatorn att lägga ut SSE/AVX instruktioner, något som är extremt svårt med "vanlig" C++.

Andra "roll your own" varianter där du står för logiken är

Edit: för att svara på om C-arrayer eller C++ vector<> är bäst, finns ingen anledning att köra med C-arrayer i C++ då vector<> är lika snabbt för själva matrisoperationerna.

Tänk bara på att den inre loopen måste iterera över den inre vector<> delen. Detta så att du gör minnesaccesserna i följd i minnet, något som ökar den spatiala lokaliteten på data-accesserna (högre CPU-cache hit rate -> snabbare).

Edit 2: Intel må ha köpt CilkArts som gör Cilk+, men tekniken finns numera implementerad i gcc (och är endera på gång för clang eller redan på plats). Så går att använda gratis.

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Medlem
Skrivet av Yoshman:

Tja det effektiva sättet att göra det är att endera använda ovan nämnda bibliotek, direkt använda SSE/AVX instrincts (inte att rekommendera) eller utnyttja någon teknik som "Cilk+ array notation".

Vill du göra det "för hand" med standard C++ är artikeln för Cilk+ ändå en bra referens då man visar logisk ekvivalent C++. Fördelen med Cilk+ metoden är dels att den är kompaktare och dels att den gör det möjligt för kompilatorn att lägga ut SSE/AVX instruktioner, något som är extremt svårt med "vanlig" C++.

Andra "roll your own" varianter där du står för logiken är

Tack, ska kika närmare på detta (speciellt Cilk+)!

Visa signatur

12c/24t 4.0GHz (Zen2) • 2x16GiB 3200MHz C14 • RTX 2080 FE 1965MHz 7000MHz • X570 I PW • Ghost S1 MKII