Miért std :: csökkentésére van szükség commutability

szavazat
5

https://en.cppreference.com/w/cpp/algorithm/reduce

Azt mondja, hogy a viselkedése egy művelet nincs meghatározva, ha a művelet nem kommutatív, de miért? Csak osztani a tömb tömb, majd egyesíteni az eredmény, ez csak akkor szükséges asszociatív?

A kérdést 13/02/2020 23:51
a forrás felhasználó
Más nyelveken...                            


3 válasz

szavazat
1

A viselkedés valójában nem determinisztikus , ha a művelet között az operandusok nem kommutatív. „nem-determinisztikus” nem ugyanaz, mint a „meghatározatlan”. Lebegőpontos matematikai nem kommutatív, például. Ez az egyik oka annak, hogy a hívást std::reducenem lehet determinisztikus, mert a bináris funkció alkalmazzák meghatározatlan sorrendben.

Lásd ezt a megjegyzést a szabvány:

Megjegyzés: A különbség reduce, és accumulateaz, hogy csökkentse vonatkozik binary_opegy meghatározatlan sorrendben, amely hozamok nem-determinisztikus eredmény nem asszociatív vagy nem-kommutatív binary_op mint például lebegőpontos összeadási. Végen jegyzet]

Válaszolt 14/02/2020 00:02
a forrás felhasználó

szavazat
1

A szabvány meghatározza a generalizált összeg az alábbiak szerint: numeric.defns

Adjuk GENERALIZED_NONCOMMUTATIVE_SUM (op, a1, ..., an) az alábbiak szerint:

  • a1 ha n értéke 1, egyébként

  • op (GENERALIZED_NONCOMMUTATIVE_SUM (op, a1, ..., ak), op (GENERALIZED_NONCOMMUTATIVE_SUM (op, aM, ..., aN)) bármely K ahol 1

Adjuk GENERALIZED_SUM (op, a1, ..., aN) mint GENERALIZED_NONCOMMUTATIVE_SUM (op, b1, ..., Bn), ahol a b1, ..., bn lehet bármilyen permutáció a1, ..., aN.

Tehát a rendelést összegzése, valamint a sorrendben operandusa meghatározhatatlan. Tehát, ha a művelet nem kommutatív vagy nem asszociatív, az eredmény nem meghatározott.

Ez is kifejezetten ide .

Ami miért: Ez adja meg a könyvtár gyártók nagyobb szabadságot, így lehet, hogy nem hajtják végre jobb. Példaként, ha a végrehajtás részesülhet kommutativitás. Tekintsük az összeget a+b+c+d+e, akkor először kiszámítja a+bés c+dpárhuzamosan. Most a+bvisszatér előtt c+d(ahogy ez megtörténhet, mert egy időben történik). Ahelyett, hogy várja a visszatérési értéke c+dmost közvetlenül kiszámítani (a+b)+e, majd adja hozzá ezt az eredményt az eredménye c+d. Így a végén, akkor számítani ((a+b)+e)+(c+d), ami átrendeződést a+b+c+d+e.

Válaszolt 14/02/2020 00:07
a forrás felhasználó

szavazat
6

std::reducemegköveteli a asszociativitás és kommutativitás. Asszociativitás egyértelműen szükség van egy párhuzamos algoritmus, mert azt szeretnénk, hogy végezze el a számítást külön darabokat, majd összekapcsolják őket.

Ami kommutativitás: szerint a reddit utáni által MSVC STL fejlesztő Billy O'Neal, erre szükség van annak érdekében, hogy a vektorizációs SIMD:

Kommutativitás is szükség van ahhoz, hogy vektorizációs, hiszen a kívánt kódot a csökkentésére, hogy jöjjön ki, mint valami ilyesmit:

vecRegister = load_contiguous(first);
while (a vector register sized chunk is left) {
    first += packSize;
    vecRegister = add_packed(load_contiguous(first), vecRegister);
}
// combine vecRegister's packed components

stb, amely adott ints és az SSE nyilvántartások és a * b * c * d * e * f * g * h ad valamit, mint (a * e) * (b * f) * (c * g) * (d * h ).

A legtöbb más nyelveken nem tesznek kifejezett dolgokat, hogy vektorizálásával azok csökkentése lehetséges. És semmi azt mondja, nem tud hozzáadni egy noncommutative_reduce vagy valami ilyesmi a jövőben, ha valaki meg nem meggyőző képesség.

Válaszolt 14/02/2020 00:13
a forrás felhasználó

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more