Re[2]: Обломатушки, ну почти.
От: Sheridan Россия  
Дата: 10.02.12 16:29
Оценка:
Как справедливо было замечено — оптимизатор г++ слишком хорош для данного случая, а я писал на работе, слишком хотел домой и не подумал об этом. Посыпаю голову пеплом, и все такое.
В общем я нагрузил алгоритм еще одной функцией, которая принимает в себя число-счетчик цикла и на его основе считает всякую фигню. Ну типа полезную работу делает.
Также я на отдельно замеряю среднее количество тиков работы этой функции и вычитаю это потом из результата.

Кратко — результаты без оптимизации и с -O2 практически выровнялись. Разница приблизительно в 1,3 раза, switch выигрывает.
Но вот, сюрприз, с -O3 switch внезапно начинает обходить if на два порядка.

Код:

#include <iostream>
#include <stdlib.h>
using namespace std;
#include <stdint.h>
#include <math.h>

#define TESTS_COUNT 100
#define SOME somework(num)
#define ELSIF(_x) else if (num == _x) { SOME; }
#define SCASE(_x) case _x: { SOME; } break;
#define CYCLE(_type, _count) for (_type i = 0; i < _count; i++)
#define LONG_CYCLE CYCLE(unsigned long long, TESTS_COUNT*TESTS_COUNT*TESTS_COUNT)
#define TESTS_COUNT_CYCLE CYCLE(int, TESTS_COUNT)

unsigned long long somewariable = 0;

static inline unsigned long long tick()
{
    unsigned long long d;
    __asm__ __volatile__ ("rdtsc" : "=A" (d) );
    return d;
}

void somework(int num)
{
    int a = sin(num);
    somewariable = cos(a+++num);
}

unsigned long long someworkTicks()
{
    unsigned long long ticks_start, ticks_end;
    ticks_start = tick();
    TESTS_COUNT_CYCLE { somework(i); }
    ticks_end = tick();
    return (ticks_end - ticks_start)/TESTS_COUNT;
}


void test_if(int num)
{
    if (num == 0) { SOME; }
    ELSIF(1)  ELSIF(2)  ELSIF(3)  ELSIF(4)  ELSIF(5)  ELSIF(6)  ELSIF(7)  ELSIF(8)  ELSIF(9)  ELSIF(10)
    ELSIF(11) ELSIF(12) ELSIF(13) ELSIF(14) ELSIF(15) ELSIF(16) ELSIF(17) ELSIF(18) ELSIF(19) ELSIF(20)
    ELSIF(21) ELSIF(22) ELSIF(23) ELSIF(24) ELSIF(25) ELSIF(26) ELSIF(27) ELSIF(28) ELSIF(29) ELSIF(30)
    ELSIF(31) ELSIF(32) ELSIF(33) ELSIF(34) ELSIF(35) ELSIF(36) ELSIF(37) ELSIF(38) ELSIF(39) ELSIF(40)
    ELSIF(41) ELSIF(42) ELSIF(43) ELSIF(44) ELSIF(45) ELSIF(46) ELSIF(47) ELSIF(48) ELSIF(49) ELSIF(50)
    ELSIF(51) ELSIF(52) ELSIF(53) ELSIF(54) ELSIF(55) ELSIF(56) ELSIF(57) ELSIF(58) ELSIF(59) ELSIF(60)
    ELSIF(61) ELSIF(62) ELSIF(63) ELSIF(64) ELSIF(65) ELSIF(66) ELSIF(67) ELSIF(68) ELSIF(69) ELSIF(70)
    ELSIF(71) ELSIF(72) ELSIF(73) ELSIF(74) ELSIF(75) ELSIF(76) ELSIF(77) ELSIF(78) ELSIF(79) ELSIF(80)
    ELSIF(81) ELSIF(82) ELSIF(83) ELSIF(84) ELSIF(85) ELSIF(86) ELSIF(87) ELSIF(88) ELSIF(89) ELSIF(90)
    ELSIF(91) ELSIF(92) ELSIF(93) ELSIF(94) ELSIF(95) ELSIF(96) ELSIF(97) ELSIF(98) ELSIF(99)
}


void test_switch(int num)
{
    switch (num)
    {
    SCASE(0)
    SCASE(1)  SCASE(2)  SCASE(3)  SCASE(4)  SCASE(5)  SCASE(6)  SCASE(7)  SCASE(8)  SCASE(9)  SCASE(10)
    SCASE(11) SCASE(12) SCASE(13) SCASE(14) SCASE(15) SCASE(16) SCASE(17) SCASE(18) SCASE(19) SCASE(20)
    SCASE(21) SCASE(22) SCASE(23) SCASE(24) SCASE(25) SCASE(26) SCASE(27) SCASE(28) SCASE(29) SCASE(30)
    SCASE(31) SCASE(32) SCASE(33) SCASE(34) SCASE(35) SCASE(36) SCASE(37) SCASE(38) SCASE(39) SCASE(40)
    SCASE(41) SCASE(42) SCASE(43) SCASE(44) SCASE(45) SCASE(46) SCASE(47) SCASE(48) SCASE(49) SCASE(50)
    SCASE(51) SCASE(52) SCASE(53) SCASE(54) SCASE(55) SCASE(56) SCASE(57) SCASE(58) SCASE(59) SCASE(60)
    SCASE(61) SCASE(62) SCASE(63) SCASE(64) SCASE(65) SCASE(66) SCASE(67) SCASE(68) SCASE(69) SCASE(70)
    SCASE(71) SCASE(72) SCASE(73) SCASE(74) SCASE(75) SCASE(76) SCASE(77) SCASE(78) SCASE(79) SCASE(80)
    SCASE(81) SCASE(82) SCASE(83) SCASE(84) SCASE(85) SCASE(86) SCASE(87) SCASE(88) SCASE(89) SCASE(90)
    SCASE(91) SCASE(92) SCASE(93) SCASE(94) SCASE(95) SCASE(96) SCASE(97) SCASE(98) SCASE(99)
    }
}

struct STicksData
{
    unsigned long long ticks_start, ticks_if, ticks_case;
};


STicksData test(int num, unsigned long long st)
{
    STicksData data;

    data.ticks_start = tick();
    TESTS_COUNT_CYCLE { test_if  (num); }
    data.ticks_if = tick();
    TESTS_COUNT_CYCLE { test_switch(num); }
    data.ticks_case = tick();

    cout << "Number: " <<  num                                    << "; ";
    cout << "if: "     << data.ticks_if   - data.ticks_start - st << "; ";
    cout << "case: "   << data.ticks_case - data.ticks_if    - st << "; ";
//    cout << "Total: " << (data.ticks_case - data.ticks_start) << endl;
    cout << endl;
    return data;
}

// -----------------------------------------------------------------------------------------------------------------------------
int main ()
{
    unsigned long long st = someworkTicks();
    STicksData allTicks[TESTS_COUNT];
    TESTS_COUNT_CYCLE
    {
        allTicks[i] = test(i, st);
    }


    unsigned long long average_if = 0, average_switch = 0, average_total = 0;
    TESTS_COUNT_CYCLE
    {
        average_if     += (allTicks[i].ticks_if   - allTicks[i].ticks_start);
        average_switch += (allTicks[i].ticks_case - allTicks[i].ticks_if   );
//      average_total  += (allTicks[i].ticks_case - allTicks[i].ticks_start);
    }
    cout << "Average ticks"  << endl;
    cout << "if:    " << (average_if    /TESTS_COUNT) << endl;
    cout << "case:  " << (average_switch/TESTS_COUNT) << endl;
//    cout << "Total: " << (average_total /TESTS_COUNT) << endl;
    return 0;
}


Результат без оптимизаций
sheridan@amd-gentoo tests % g++ if-case.cpp -o si; ./si
Number: 0; if: 5231; case: 6546; 
Number: 1; if: 24566; case: 22647; 
Number: 2; if: 23597; case: 22243; 
Number: 3; if: 31683; case: 29458; 
Number: 4; if: 51127; case: 29016; 
Number: 5; if: 31886; case: 29061; 
Number: 6; if: 31513; case: 28714; 
Number: 7; if: 31786; case: 28620; 
Number: 8; if: 31776; case: 28919; 
Number: 9; if: 31904; case: 29244; 
Number: 10; if: 32425; case: 29664; 
Number: 11; if: 31117; case: 28366; 
Number: 12; if: 32097; case: 28867; 
Number: 13; if: 31611; case: 28141; 
Number: 14; if: 33479; case: 29676; 
Number: 15; if: 33580; case: 29522; 
Number: 16; if: 50382; case: 29407; 
Number: 17; if: 33329; case: 29133; 
Number: 18; if: 33596; case: 29043; 
Number: 19; if: 39218; case: 34562; 
Number: 20; if: 34180; case: 28986; 
Number: 21; if: 34255; case: 29009; 
Number: 22; if: 33630; case: 27863; 
Number: 23; if: 35377; case: 29243; 
Number: 24; if: 34797; case: 29131; 
Number: 25; if: 35607; case: 28884; 
Number: 26; if: 36327; case: 29578; 
Number: 27; if: 35423; case: 29065; 
Number: 28; if: 36542; case: 29335; 
Number: 29; if: 36879; case: 29490; 
Number: 30; if: 35878; case: 29060; 
Number: 31; if: 36646; case: 28718; 
Number: 32; if: 36722; case: 29118; 
Number: 33; if: 35970; case: 28095; 
Number: 34; if: 37538; case: 29156; 
Number: 35; if: 38570; case: 29495; 
Number: 36; if: 38164; case: 29271; 
Number: 37; if: 37878; case: 28412; 
Number: 38; if: 38150; case: 29236; 
Number: 39; if: 56391; case: 29382; 
Number: 40; if: 38712; case: 28866; 
Number: 41; if: 39742; case: 29639; 
Number: 42; if: 39191; case: 29015; 
Number: 43; if: 38907; case: 28566; 
Number: 44; if: 39041; case: 28056; 
Number: 45; if: 40340; case: 28621; 
Number: 46; if: 40109; case: 28942; 
Number: 47; if: 39556; case: 28217; 
Number: 48; if: 40690; case: 29233; 
Number: 49; if: 40788; case: 44688; 
Number: 50; if: 41130; case: 28763; 
Number: 51; if: 41332; case: 28204; 
Number: 52; if: 41438; case: 29065; 
Number: 53; if: 42243; case: 29456; 
Number: 54; if: 43001; case: 29435; 
Number: 55; if: 41579; case: 28384; 
Number: 56; if: 42199; case: 28714; 
Number: 57; if: 42592; case: 28779; 
Number: 58; if: 42065; case: 28445; 
Number: 59; if: 43884; case: 29505; 
Number: 60; if: 60339; case: 29813; 
Number: 61; if: 43706; case: 28976; 
Number: 62; if: 48062; case: 32434; 
Number: 63; if: 43802; case: 28126; 
Number: 64; if: 45031; case: 29376; 
Number: 65; if: 48779; case: 33106; 
Number: 66; if: 43914; case: 28312; 
Number: 67; if: 45479; case: 29204; 
Number: 68; if: 45589; case: 28597; 
Number: 69; if: 44685; case: 28006; 
Number: 70; if: 63052; case: 29261; 
Number: 71; if: 46060; case: 28876; 
Number: 72; if: 46894; case: 29504; 
Number: 73; if: 47547; case: 29568; 
Number: 74; if: 46261; case: 29076; 
Number: 75; if: 47006; case: 28954; 
Number: 76; if: 47176; case: 28883; 
Number: 77; if: 46175; case: 28063; 
Number: 78; if: 47973; case: 28995; 
Number: 79; if: 48552; case: 29471; 
Number: 80; if: 63565; case: 28460; 
Number: 81; if: 48263; case: 28755; 
Number: 82; if: 48757; case: 28686; 
Number: 83; if: 58056; case: 39099; 
Number: 84; if: 49034; case: 29012; 
Number: 85; if: 49800; case: 29524; 
Number: 86; if: 49821; case: 29114; 
Number: 87; if: 49565; case: 29174; 
Number: 88; if: 49211; case: 28151; 
Number: 89; if: 50038; case: 46191; 
Number: 90; if: 51031; case: 29290; 
Number: 91; if: 49965; case: 28308; 
Number: 92; if: 50858; case: 28995; 
Number: 93; if: 50861; case: 29106; 
Number: 94; if: 51611; case: 28811; 
Number: 95; if: 51044; case: 28643; 
Number: 96; if: 51846; case: 28945; 
Number: 97; if: 52293; case: 29051; 
Number: 98; if: 52979; case: 29463; 
Number: 99; if: 68037; case: 28276; 
Average ticks
if:    42928
case:  29964


и результат с оптимизациями

sheridan@amd-gentoo tests % g++ if-case.cpp -O2 -o si; ./si
Number: 0; if: 4209; case: 3988; 
Number: 1; if: 23017; case: 20805; 
Number: 2; if: 22176; case: 21267; 
Number: 3; if: 29033; case: 27017; 
Number: 4; if: 28951; case: 26887; 
Number: 5; if: 29551; case: 26269; 
Number: 6; if: 29417; case: 26552; 
Number: 7; if: 30218; case: 26902; 
Number: 8; if: 30245; case: 27421; 
Number: 9; if: 30333; case: 26417; 
Number: 10; if: 30684; case: 27439; 
Number: 11; if: 29689; case: 25796; 
Number: 12; if: 30690; case: 26389; 
Number: 13; if: 30716; case: 26126; 
Number: 14; if: 30436; case: 26980; 
Number: 15; if: 31014; case: 27260; 
Number: 16; if: 31928; case: 27430; 
Number: 17; if: 31167; case: 27161; 
Number: 18; if: 31588; case: 26756; 
Number: 19; if: 37303; case: 32483; 
Number: 20; if: 32075; case: 26611; 
Number: 21; if: 32329; case: 27356; 
Number: 22; if: 31538; case: 25823; 
Number: 23; if: 33278; case: 26851; 
Number: 24; if: 32300; case: 26452; 
Number: 25; if: 32848; case: 26228; 
Number: 26; if: 32981; case: 52079; 
Number: 27; if: 32921; case: 27266; 
Number: 28; if: 33344; case: 26495; 
Number: 29; if: 33787; case: 27166; 
Number: 30; if: 33133; case: 26348; 
Number: 31; if: 33285; case: 26431; 
Number: 32; if: 34007; case: 26244; 
Number: 33; if: 32537; case: 25790; 
Number: 34; if: 34048; case: 27169; 
Number: 35; if: 34659; case: 27186; 
Number: 36; if: 34496; case: 26677; 
Number: 37; if: 34159; case: 26197; 
Number: 38; if: 34361; case: 26835; 
Number: 39; if: 34949; case: 26227; 
Number: 40; if: 34886; case: 27272; 
Number: 41; if: 35556; case: 26942; 
Number: 42; if: 34803; case: 26778; 
Number: 43; if: 35009; case: 26524; 
Number: 44; if: 35071; case: 25744; 
Number: 45; if: 35387; case: 26404; 
Number: 46; if: 35842; case: 27084; 
Number: 47; if: 35195; case: 26448; 
Number: 48; if: 36233; case: 26799; 
Number: 49; if: 35613; case: 26100; 
Number: 50; if: 36303; case: 26822; 
Number: 51; if: 35928; case: 26774; 
Number: 52; if: 36706; case: 27083; 
Number: 53; if: 36935; case: 27179; 
Number: 54; if: 37230; case: 26991; 
Number: 55; if: 36007; case: 25683; 
Number: 56; if: 36930; case: 27034; 
Number: 57; if: 36650; case: 26674; 
Number: 58; if: 67032; case: 25945; 
Number: 59; if: 37737; case: 27212; 
Number: 60; if: 38216; case: 27033; 
Number: 61; if: 37665; case: 26877; 
Number: 62; if: 42001; case: 30204; 
Number: 63; if: 38155; case: 26088; 
Number: 64; if: 38277; case: 27103; 
Number: 65; if: 43066; case: 31050; 
Number: 66; if: 38204; case: 26345; 
Number: 67; if: 39259; case: 26782; 
Number: 68; if: 38724; case: 26011; 
Number: 69; if: 38374; case: 26122; 
Number: 70; if: 39079; case: 26555; 
Number: 71; if: 39282; case: 27073; 
Number: 72; if: 39809; case: 27182; 
Number: 73; if: 40076; case: 53457; 
Number: 74; if: 39444; case: 26076; 
Number: 75; if: 39822; case: 26332; 
Number: 76; if: 40346; case: 26030; 
Number: 77; if: 149570; case: 25790; 
Number: 78; if: 40716; case: 26751; 
Number: 79; if: 40952; case: 27367; 
Number: 80; if: 39761; case: 25574; 
Number: 81; if: 40754; case: 26246; 
Number: 82; if: 40939; case: 26086; 
Number: 83; if: 49030; case: 34838; 
Number: 84; if: 41213; case: 27083; 
Number: 85; if: 41758; case: 27152; 
Number: 86; if: 42409; case: 27123; 
Number: 87; if: 43000; case: 53662; 
Number: 88; if: 42675; case: 26538; 
Number: 89; if: 43145; case: 26614; 
Number: 90; if: 44291; case: 27052; 
Number: 91; if: 43460; case: 26231; 
Number: 92; if: 43756; case: 26715; 
Number: 93; if: 43953; case: 26526; 
Number: 94; if: 44467; case: 26277; 
Number: 95; if: 44110; case: 26795; 
Number: 96; if: 44143; case: 27034; 
Number: 97; if: 44582; case: 26810; 
Number: 98; if: 44488; case: 27128; 
Number: 99; if: 43353; case: 25541; 
Average ticks
if:    38416
case:  28164



Но что примечательно — с -O3 становится веселее:
sheridan@amd-gentoo tests % g++ if-case.cpp -O3 -o si; ./si
Number: 0; if: 755; case: 609; 
Number: 1; if: 551; case: 369; 
Number: 2; if: 581; case: 92; 
Number: 3; if: 693; case: 95; 
Number: 4; if: 935; case: 321; 
Number: 5; if: 993; case: 84; 
Number: 6; if: 1075; case: 62; 
Number: 7; if: 1150; case: 51; 
Number: 8; if: 1226; case: 51; 
Number: 9; if: 1426; case: 36; 
Number: 10; if: 1528; case: 39; 
Number: 11; if: 1985; case: 39; 
Number: 12; if: 1831; case: 357; 
Number: 13; if: 2030; case: 39; 
Number: 14; if: 2133; case: 39; 
Number: 15; if: 2337; case: 39; 
Number: 16; if: 2732; case: 39; 
Number: 17; if: 2511; case: 39; 
Number: 18; if: 2730; case: 36; 
Number: 19; if: 2834; case: 39; 
Number: 20; if: 3037; case: 183; 
Number: 21; if: 3137; case: 39; 
Number: 22; if: 3338; case: 36; 
Number: 23; if: 3530; case: 39; 
Number: 24; if: 3512; case: 39; 
Number: 25; if: 3730; case: 36; 
Number: 26; if: 3912; case: 39; 
Number: 27; if: 4135; case: 36; 
Number: 28; if: 4131; case: 39; 
Number: 29; if: 4236; case: 39; 
Number: 30; if: 4410; case: 39; 
Number: 31; if: 4612; case: 39; 
Number: 32; if: 4811; case: 39; 
Number: 33; if: 4812; case: 39; 
Number: 34; if: 5011; case: 39; 
Number: 35; if: 5230; case: 39; 
Number: 36; if: 5354; case: 36; 
Number: 37; if: 5411; case: 39; 
Number: 38; if: 5512; case: 39; 
Number: 39; if: 35450; case: 59; 
Number: 40; if: 33589; case: 84; 
Number: 41; if: 64275; case: 78; 
Number: 42; if: 33887; case: 57; 
Number: 43; if: 33161; case: 33; 
Number: 44; if: 33144; case: 83; 
Number: 45; if: 33733; case: 70; 
Number: 46; if: 34546; case: 46; 
Number: 47; if: 36962; case: 95; 
Number: 48; if: 34618; case: 46; 
Number: 49; if: 34053; case: 52; 
Number: 50; if: 35044; case: 84; 
Number: 51; if: 34377; case: 62; 
Number: 52; if: 35185; case: 57; 
Number: 53; if: 35544; case: 68; 
Number: 54; if: 36047; case: 70; 
Number: 55; if: 34518; case: 73; 
Number: 56; if: 35847; case: 84; 
Number: 57; if: 35945; case: 78; 
Number: 58; if: 35175; case: 70; 
Number: 59; if: 36113; case: 62; 
Number: 60; if: 36823; case: 55; 
Number: 61; if: 36445; case: 46; 
Number: 62; if: 40863; case: 44; 
Number: 63; if: 36349; case: 33; 
Number: 64; if: 37601; case: 46; 
Number: 65; if: 41454; case: 33; 
Number: 66; if: 39935; case: 59; 
Number: 67; if: 37331; case: 33; 
Number: 68; if: 37041; case: 166; 
Number: 69; if: 36971; case: 33; 
Number: 70; if: 38330; case: 33; 
Number: 71; if: 38005; case: 33; 
Number: 72; if: 38024; case: 51; 
Number: 73; if: 38669; case: 64; 
Number: 74; if: 71977; case: 33; 
Number: 75; if: 38371; case: 33; 
Number: 76; if: 38512; case: 171; 
Number: 77; if: 37720; case: 33; 
Number: 78; if: 39114; case: 33; 
Number: 79; if: 39354; case: 33; 
Number: 80; if: 38091; case: 46; 
Number: 81; if: 39491; case: 33; 
Number: 82; if: 38923; case: 33; 
Number: 83; if: 47743; case: 66; 
Number: 84; if: 39830; case: 195; 
Number: 85; if: 40184; case: 33; 
Number: 86; if: 40256; case: 33; 
Number: 87; if: 40155; case: 33; 
Number: 88; if: 39334; case: 33; 
Number: 89; if: 41203; case: 33; 
Number: 90; if: 41140; case: 33; 
Number: 91; if: 43434; case: 33; 
Number: 92; if: 40837; case: 33; 
Number: 93; if: 40885; case: 33; 
Number: 94; if: 41071; case: 33; 
Number: 95; if: 41320; case: 62; 
Number: 96; if: 43622; case: 26; 
Number: 97; if: 41465; case: 46; 
Number: 98; if: 42022; case: 33; 
Number: 99; if: 43249; case: 293; 
Average ticks
if:    25858
case:  945
Matrix has you...