Módosítások

Intel Xeon Phi

1 687 bájt hozzáadva, 2016. május 4., 09:58
AoS -> SoA
====SIMD====
====AoS -> SoA====
A kiindulás probléma az, hogy a struktúrákat tartalmazó vektort nem lehet jól vektorizálni, mivel a cache-ben tárolt adatok nagy többsége feleslegesen van bent, mivel azon adatokat csak egy későbbi ciklus futás során fogja az alkalmazás feldolgozni. Tehát ezen adatok jelenleg feleslegesen foglalják a cache területet, ahelyett, hogy hasznos adatot tárolnánk ott.
<pre>
struct MyStructure {
float x, y, z;
}
 
void My_Function(cons int nItem, MyStructure* const Items, const float delta) {
for (int i = 0; i < nItem; i++) {
...
for (int j = 0; j < nItem; j++) {
const float dx = Items[j].x - Items[i].x;
const float dy = Items[j].y - Items[i].y;
const float dz = Items[j].z - Items[i].z;
...
}
}
...
}
</pre>
 
A vektorban a struktúrák tárolása helyett minden elemnek egy dedikált vektort allokálunk és így könnyen tudja a fordító vektorizálni azt. Természetesen segítségként a vektor feldolgozását "tömbösítettük" a tileSize méret megadásával illetve a ''unroll'' fordítási direktíva segítségével.
<pre>
struct MyStructureSet {
float *x, *y, *z;
}
 
void My_Function(cons int nItem, MyStructure* const Items, const float delta) {
const int tileSize = 16;
#pragma omp parallel for schedule(guided)
for (int ii = 0; ii < nItem; ii+= tileSize) {
...
#pragma unroll(tileSize)
for (int j = 0; j < nItem; j++) {
#pragma unroll(tileSize)
for (int i = ii; i < ii + tileSize; i++) {
const float dx = Items.x[j] - Items.x[i];
const float dy = Items.y[j] - Items.y[i];
const float dz = Items.z[j] - Items.z[i];
...
}
}
}
...
}
</pre>
 
====Hatékony hossz választás====
Olyan esetben jelent előnyt, ha például az n*n-es mátrix esetén n nem osztható 16-val, mert akkor a vektorizáció nem teljesen hajtható végre.
98
szerkesztés

Navigációs menü