WebHU - Programozási kérdések és válaszok

Változik-e az adott adattípuson végzett aritmetikai műveletek költsége az operandus értékektől függően?

Ha elvégzek egy C-ben írt számítást, például mátrix-mátrix összeadást vagy mátrix-mátrix szorzást, ahol a munka egy for ciklusban történik, minden iteráción azonos számú és típusú aritmetikai művelettel, akkor a konkrét értékei a bemeneti adatok befolyásolják a számítás sebességét? Például, ha a mátrixelemek 32 bites egész számok, amelyek értéke 0 és 127 között van, és a reprezentációjuk csak négy megfelelő bájtból egyben változik, akkor az gyorsabban futna, mintha az értékek 0 és INT_MAX között változnának (feltételezve, hogy nem meghatározatlan viselkedés fordul elő)?

Ha tippelnem kellene, azt mondanám, hogy nem, mert akár kicsi, akár nagyon nagy az érték, mivel 32 bites egész számként van definiálva, akkor maszkolásra kerül, hogy ugyanannyi memóriaterületen elférjen, így a kicsi és a nagy az értékeknek végül ugyanannyi bájt lesz a memóriájában. Jól gondolom ezt? Más az egyszeres/kettős pontosságú lebegőpontos számoknál?

14.12.2016

  • Nem világos, hogy mi a problémád. Ha benchmarkot szeretne végezni, olvassa el, hogyan kell ezt megfelelően csinálni. Ha egyéb problémái vannak, pontosabbnak kell lennie. 15.12.2016
  • A modern CPU-hardveren az egyetlen adatfüggő teljesítményű művelet az (int és FP) az osztás és az sqrt. (Gyakran változó késleltetésűek, és nincsenek teljesen folyamatban; lásd: a közelmúltban a Collatz-sejtés kézzel írt asm-kérdése, hogy többet megtudjon a DIV versus műszakokról, például). Az add/sub/mul/shift mind rögzített késleltetés/áteresztőképesség. Ez határozottan igaz az összes jelenlegi x86-os CPU-ra, és szinte biztosan igaz a legtöbb más rendszerre is. 15.12.2016
  • @Olaf Konkrét problémám nincs, csak kíváncsi vagyok. Levettem a benchmarking címkét arra az esetre, ha úgy tűnhetne, hogy konkrét benchmarking kérdésem lenne. Úgy gondoltam, hogy egy kernel benchmark jó példa lenne annak illusztrálására, amit kérdezni próbálok. 15.12.2016
  • @PeterCordesnek igaza van. A legtöbb modern architektúrán a típus természetesen számít, de nem az érték a legtöbb alapvető ALU-műveletnél. 15.12.2016
  • @DBPriGuy: Ez pl. a megosztás sokat számít. Rosszabb: csúcskategóriás CPU-kon az érték még egyciklusú műveleteknél is számíthat: sok kapcsoló csomópont a CPU-ban több hőt termel, ami csökkenti az órajelet pl. vékony vonalú notebookok vagy mobiltelefonok. Vagy akár normál asztali gépekhez is, ha turbó sebességű módokat használnak. 15.12.2016
  • @PeterCordes: Ebbe beletartoznak a NaN-eken, a végteleneken és a szubnormálisokon végzett műveletek? 15.12.2016
  • @Olaf: Egyetértek, ezért mondtam a legtöbbet. 15.12.2016
  • @DBPriGuy: A Core-i-n, ARMv7A/v8A-n, a jelenlegi AMD-n (és valószínűleg a Zenen), a POWER-en vagy az Nvidia és AMD GPU-kon kívül melyik architektúrát tartja a legmodernebbnek? 15.12.2016
  • @Olaf: Sóhajt, úgy tűnik, nehezen értjük meg egymást. A legtöbb műveletre utaltam, elnézést kérek az egyértelműség hiányáért. Lényegében egyetértek Peter Cordesszal. 15.12.2016
  • @DBPriGuy: Az összes műveletre utalok. Minden sértés nélkül: itt a digitális elektronikáról, a CMOS technológiáról, az energiagazdálkodásról és a dinamikus órajelről van szó; nagyon mély ismeretekre van szüksége erről a problémák megértéséhez. A dolgok nagyon bonyolulttá váltak, mivel a CPU-k rendkívül dinamikusan változtatják órajelüket az energiafogyasztással és a szerszám hőmérsékletével. Néhányan még azt is megváltoztatják attól függően, hogy melyik fizikai tartomány melegszik fel, azaz melyik része a szerszámnak a hőmérséklet-emelkedésnek, és az egyik óraciklusról a másikra. Az óra 50 vagy több százalékkal változhat. 15.12.2016
  • Még akkor is, ha a műveletenkénti költség nem változik az operandus értékeivel, ha a műveletek eredményét elágazási feltételben használjuk, akkor mindig ugyanazok az operandusértékek azt eredményezik, hogy az elágazás mindig ugyanazon az úton halad. Az a CPU, amely dinamikus elágazás előrejelzést hajt végre a végrehajtás felgyorsítása érdekében (mint minden modern PC-osztályú CPU), valószínűleg gyorsabban fut, mintha a vonatkozó operandusértékek véletlenszerűek lennének. 15.12.2016
  • @JohnBollinger Az, hogy a mátrix értékei azonosak, csak egy mód volt számomra, hogy leegyszerűsítsem a kérdést és tömörítsem. Valójában csak az érdekel, hogy egy számítás mennyi időt vesz igénybe az elejétől a végéig. Például: for(i=0;i<size;i++) { C[i]=A[i]+B[i]; } 15.12.2016
  • @ShaunHoltzman, akkor fogalmam sincs, mit kérdezel valójában. Amennyire meg tudom állapítani, az értékek azonosságának hatása egyáltalán nem mellékes a kérdés szempontjából – éppen ellenkezőleg, úgy tűnik, hogy ez áll a középpontban. 15.12.2016
  • @JohnBollinger Arra próbálok rájönni, ha például összeadok két 32 bites mátrixot nagy számokkal, A[0] = 1 021 000 398 A[1] = 1 278 236 282...+B[0] = 2 102 123 010 B[1] = 1 009 876 148... for ciklusban ez lassabb lesz, mintha ugyanezt a ciklusnál kisebb 32 bites számokkal, például A[0] = 3 A[1] = 2 ... stb. + B[0] = 9 B[1] = 6. A számok azonos adattípusúak (32 bites egész számok), de az egyik esetben mindegyik nagyon nagy, a másik esetben kicsi. Eltérne-e a teljesítmény, vagy hasonló, mivel még mindig 32 bites egész számok vannak a memóriában 15.12.2016
  • @Olaf: Szóval nem értesz egyet Peter Cordesszal? 15.12.2016
  • @DBPriGuy: Nem. Peter az órajelekről beszél, ami egy szinkron CPU-ban helyes (ami minden nagyobb CPU ilyen). Az időről beszélek. Nem a ciklusok száma változhat, hanem az egyes ciklusok hossza. Vegye figyelembe, hogy az OP az időt kérdezi (ami ésszerű egy program esetében). De sok más hatás is van egy rendszerben. A megfelelő benchmarking nem kezdő dolga. A viszonyítási alapok hazudnak, a hazugok mérnek – ennek a közmondásnak nagyon komoly háttere van. Ma sokkal többet, mint ahonnan származik (ezt az 1980-as évek óta tudom; lehet, hogy sokkal régebbi). 15.12.2016
  • @Olaf: Á, újraolvastam mindent, amit írtál, és most már értem, amit mondasz. Köszönjük, hogy megosztotta tudását! 15.12.2016
  • @ShaunHoltzman, ebben az esetben úgy szerkesztettem meg a kérdésedet, hogy tisztábban fejezzem ki azt, amit most megértettem. 15.12.2016
  • @JohnBollinger köszönöm, a szerkesztésed határozottan segít a kérdésem jobb megfogalmazásában. 15.12.2016
  • @JohnBollinger: remek pont, Shaunnak meg kellene néznie a SO legtöbb szavazatot kapott kérdését: Miért gyorsabb egy rendezett tömb feldolgozása, mint egy rendezetlen tömb?. 15.12.2016
  • @user2357112: jó kérdés. x86-on SSE-vel: NaN és Infinity bemenetként/kimenetként: nincs büntetés. X86-on x87-es örökölt FPU-val: NaN és Infinity: nagy lassulás. Denormálisak: a mikroarchitektúrától függ, de sokan a mikrokódba csapdázzák, hogy kezeljék. Az Intel Sandybridge gyors denormálokat tartalmaz az összeadáshoz/kivonáshoz, de nem a szorzáshoz. Az IIRC, az AMD hardverben mindig denormál dolgokat csinál. Természetesen az FTZ (nullára öblítés) és a DAZ (a bemeneti denormális értékek nulla) beállítása ezeket elkerüli. 15.12.2016

Válaszok:


1

A változóban lévő adatok nem befolyásolják a teljesítményt, ez csak egy tárhely. Ha a tárterületen lévő adatokat valamilyen módon manipulálni kell, teljesítményproblémák léphetnek fel. Íme néhány figyelembe veendő dolog, amelyek befolyásolhatják az ezzel kapcsolatos teljesítményt.

  1. A CPU hardveres architektúrájától függően (azaz HW FPU vs SW lebegőpontos megvalósítás, csővezetékes vagy nem csővezetékes stb...) a CPU-igényes matematikai műveletek (pl. osztás, négyzetgyök stb.) végrehajtása különböző adatkészleteken befolyásolja a teljesítményt.

  2. Egy másik forgatókönyv, amely hatással lehet a teljesítményre, az, hogy a változó hol található a memóriában. A változó byte úgy van igazítva, hogy az adatok eléréséhez csak egy utasításciklusra van szükség? Vagy rosszul van beállítva, ezért az összes adat lekéréséhez extra utasításciklusra van szükség. Gyakran ezekben az esetekben a fordító speciális kulcsszavakat vagy akár pragmákat tartalmaz, amelyek kényszeríthetik a változók igazítását az optimalizálás érdekében.

Üdvözlettel!

14.12.2016
  • A normál fordítóprogramok normál platformokhoz (például az x86) mindig igazítják az egész számokat, a lebegőpontokat és a duplájukat a természetes igazításukhoz (pl. 8 bájt 8 bájtos értékek esetén). Kifejezetten __attribute__((packed))-t vagy hasonló pragmát kell használnia ennek felülbírálásához egy struktúrán belül. Az adatok struktúrákba való elrendezése a kitöltés elkerülése érdekében különbséget tehet a között, hogy a teljes struktúra egy gyorsítótár-sorba illeszkedik-e vagy sem, ami nagyobb léptékű gyorsítótár találati arányt eredményezhet több struktúrán keresztül. 15.12.2016
  • Remek pont! Leginkább a beágyazott világban dolgozom és sajnos ez nem mindig van így :(. Az igazítást a fejlesztőnek kell erőltetnie és elszámolnia, ahogy fentebb említettem. 15.12.2016
  • Az OP kérdésének kibővítésével és az eredeti kérdéshez kapcsolódó további információkkal nincs semmi baj. Ne trollkodj, és ne jelöld meg azokat a válaszokat, ahol nem adtál hasznos információt a témában, vagy építő kritikát a válasz jobbá tételére vonatkozóan. 15.12.2016
  • Egyetértek azzal, hogy a további információk hasznosak lehetnek, de csak akkor, ha a kérdésre is választ kapnak. Ne próbálja megmondani, mit tegyek, bárki, aki bármilyen okból szabadon szavazhat. De tulajdonképpen egy javaslatot tettem a válasz jobbá tételére: Válaszolj a kérdésre. 15.12.2016
  • @alain: Frissítettem a válaszomat, hogy egyértelműen válaszoljak a kérdésre a megjegyzések részben megadott visszajelzésekből. Ezenkívül megadtam néhány további információt is, amelyek befolyásolhatják a teljesítményt. Köszönjük hozzájárulását! 15.12.2016
  • Új anyagok

    A rádiógomb ellenőrzött eseményének használata a jQueryben
    Ebben a cikkben látni fogjuk, hogyan kell dolgozni a jquery választógombbal ellenőrzött eseményeivel. A választógombok HTML gombok, amelyek segítenek kiválasztani egyetlen értéket egy csoportból...

    Körkörös függőségek megoldása terraformban adatforrásokkal – lépésről lépésre
    Mi az a körkörös függőségek Dolgozzunk egy egyszerű eseten, amikor az SQS-sor és az S3-vödör közötti körkörös függőség problémája van egy egymástól függő címkeérték miatt. provider..

    Miért érdemes elkezdeni a kódolást 2023-ban?
    01100011 01101111 01100100 01100101 — beep boop beep boop Világunk folyamatosan fejlődik a technológia körül, és naponta fejlesztenek új technológiákat a valós problémák megoldására. Amint..

    🎙 Random Noise #2  – Örökbefogadás és hit
    az analitika íratlan világának gondozása Szeretné, hogy ezek a frissítések a postaládájába kerüljenek? Iratkozzon fel itt . "Ha önvezető autókat gyártanak, akkor mi miért ne..

    A legrosszabb politika és prediktív modellek májátültetésre jelöltek számára az Egyesült Államokban
    A máj (vagy óangolul lifer) az emberi test legnehezebb belső szervére utal, amely csendesen működik a nap 24 órájában. Mit csinál a máj? 500 feladatot hajt végre a szervezet egészségének..

    5 webhely, amely 2022-ben fejleszti front-end fejlesztői készségeit
    Frontendmentor.io A tényleges projektek létrehozásával a Frontendmentor.io segítséget nyújt a front-end kódolási képességeinek fejlesztésében. A kódolást azután kezdheti meg, hogy..

    Mikor kell használni a Type-t az interfészhez képest a TypeScriptben?
    A TypeScript a JavaScript gépelt szuperkészlete, amely statikus gépelést ad a nyelvhez. Ez megkönnyíti a robusztus és karbantartható kód írását azáltal, hogy a hibákat a fordítási időben..