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

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Sep 2013

[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?

Main || Intel Core i7 980X @ 4.12GHz || ASUS Rampage III Gene || Corsair Vengeance 6x4GB @ 1800MHz || EVGA GTX 780 Reference || Creative Sound Blaster ZxR || 2x Intel 530 240 GB || Western Digital Blue WD10EZEX 1000 GB || ASUS VG248QE (no G-sync) ||
Laptop || Lenovo Thinkpad X220 4291-37G ||
Project: Pentium Clockbox || Intel Pentium G3258 ||

Trädvy Permalänk
Datavetare
Plats
Stockholm
Registrerad
Jun 2011

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

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

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Sep 2013
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

Main || Intel Core i7 980X @ 4.12GHz || ASUS Rampage III Gene || Corsair Vengeance 6x4GB @ 1800MHz || EVGA GTX 780 Reference || Creative Sound Blaster ZxR || 2x Intel 530 240 GB || Western Digital Blue WD10EZEX 1000 GB || ASUS VG248QE (no G-sync) ||
Laptop || Lenovo Thinkpad X220 4291-37G ||
Project: Pentium Clockbox || Intel Pentium G3258 ||

Trädvy Permalänk
Datavetare
Plats
Stockholm
Registrerad
Jun 2011

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.

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

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Sep 2013
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+)!

Main || Intel Core i7 980X @ 4.12GHz || ASUS Rampage III Gene || Corsair Vengeance 6x4GB @ 1800MHz || EVGA GTX 780 Reference || Creative Sound Blaster ZxR || 2x Intel 530 240 GB || Western Digital Blue WD10EZEX 1000 GB || ASUS VG248QE (no G-sync) ||
Laptop || Lenovo Thinkpad X220 4291-37G ||
Project: Pentium Clockbox || Intel Pentium G3258 ||