LINUX.ORG.RU

Объясните сишную магию

 ,


11

14

Пытался понять как реализовать SVG фильтр feComposite, ибо SVG дока унылая, поэтому залез в сорцы вебкита. Там тоже документации ноль, ещё и код очень странный.

Вот что это за ужас (src):

static unsigned char clampByte(int c)
{
    unsigned char buff[] = { static_cast<unsigned char>(c), 255, 0 };
    unsigned uc = static_cast<unsigned>(c);
    return buff[!!(uc & ~0xff) + !!(uc & ~(~0u >> 1))];
}

Я так понимаю, они проверяют что int в 0..255 диапазоне, но уж слишком странным образом.

UPD: коммит, который добавил этот код.

★★★★★

Последнее исправление: RazrFalcon (всего исправлений: 1)

Ответ на: комментарий от anonymous

IDB от UB отличается фундаментально.

Это постулируется в стандартах С и С++, вроде. Фундаментально - это когда стандарт С или С++ являются как минимум непротиворечивыми теориями.

anonymous
()
Ответ на: комментарий от NishiragiShintaro

Например, на входных значениях от -500 до 500 lamerok будет быстрее webkit? У Вас код слишком элитный для меня(неплюсовика), поэтому не вижу какой диапазон.

Deleted
()

Вариант «мультиплексор».

unsigned char clampByteMux(int c)
{
    unsigned neg = ~0u * (c < 0);
    unsigned big = ~0u * (c > 255);

    return (c & ~neg & ~big) | (~0u & ~neg & big);
}
Говнистость ассемблерного кода значительно зависит от версии компилятора. Например, clang 3.0 весьма хорош:
clampByteMux(int):                      # @clampByteMux(int)
        cmp     EDI, 255
        mov     EAX, 255
        cmovle  EAX, EDI
        sar     EDI, 31
        not     EDI
        and     EDI, EAX
        movzx   EAX, DIL
        ret
В чётвертой версии он похудшел
clampByteMux(int):                      # @clampByteMux(int)
        mov     ecx, edi
        sar     ecx, 31
        not     ecx
        mov     edx, ecx
        and     edx, edi
        xor     esi, esi
        cmp     edi, 255
        mov     eax, -1
        cmovle  eax, esi
        cmovle  esi, edx
        and     eax, ecx
        or      eax, esi
        ret
Но потом исправился (с 5-го по trunk выдаёт примерно то же, что и 3.0.0).

На то, что выдаёт gcc, лучше не смотреть:

clampByteMux(int):
        xor     eax, eax
        mov     ecx, edi
        cmp     edi, 255
        setg    al
        shr     ecx, 31
        sub     ecx, 1
        lea     edx, [rax-1]
        neg     eax
        and     edx, ecx
        and     eax, ecx
        and     edx, edi
        or      eax, edx
        ret

anonymous
()
Ответ на: комментарий от anonymous

(c & ~neg & ~big) | (~0u & ~neg & big)

После всех упрощений ~neg & (c | big) И GCC с этим справляется лучше.

anonymous
()
Ответ на: комментарий от anonymous

Вариант «мультиплексор».

Кстати, да. И не UB (для особо дотошных - не IDB) и защита от тайминг атак.
Но, блин, я не настолько крут, чтобы в уме строить мультиплексоры (оптимизированные).

anonymous
()
Ответ на: комментарий от anonymous

И не UB (для особо дотошных - не IDB)

Но как жи c & ~neg? Ведь мы читаем из c биты которые туда не записывали!!!

Но, блин, я не настолько крут, чтобы в уме строить мультиплексоры

А зачем их в уме строить? Можно на бумажке построить.

anonymous
()
Ответ на: комментарий от anonymous

Но как жи c & ~neg? Ведь мы читаем из c биты которые туда не записывали!!!

Читаем всё или ничего, а не конкретные биты по битовой маске.
Ты тот самый дотошный аноним? Если да, то игнор.

anonymous
()

Не подскажите, а такого же типа оптимизации (отсутствие ветвления) применимы в языках высокого уровня (читать хипсерские), например в JS, или там это экономия на спичках?

abs ★★★
()
Ответ на: комментарий от Deleted
struct config_t {
  struct data {
    using type = int32_t;//это тип данных, от которых выполняется операция
    static constexpr auto min = -512, max = 512;//это минимальное и максимальное значение
    static constexpr auto size = 1024ul * 1000 * 100;//это кол-во данных в датасете на котором бенчится.
  };
};

Я поставил -512 до 512. Все результаты с ними.

NishiragiShintaro
()
Ответ на: комментарий от anonymous

Ты тот самый дотошный аноним?

Нет.

anonymous
()
Ответ на: комментарий от anonymous

Там рантайм ветвится и тормозит когда хочет, а не так, как у тебя в коде написано.

Но код JIT-ится который написан.

anonymous
()
Ответ на: комментарий от anonymous
g++ -O3 -march=native -fwhole-program
clamp::std       0.148sec(690244613cps), sum = 9807621259
clamp::ffmpeg    0.149sec(689126594cps), sum = 9807621259
clamp::naive     0.390sec(262636450cps), sum = 9807621259
clamp::lamerok   0.390sec(262376145cps), sum = 9807621259
clamp::webkit    0.175sec(586751158cps), sum = 9807621259
clamp::webkitv2  0.197sec(520843678cps), sum = 9807621259
clamp::tsar      0.148sec(690917688cps), sum = 9807621259
clamp::bytemux   0.148sec(693911624cps), sum = 9807621259
clamp::bait      0.148sec(693417170cps), sum = 9807621259

clang++ -O3 -march=native -fwhole-program
clamp::std       0.148sec(693273633cps), sum = 9809494115
clamp::ffmpeg    0.128sec(801748845cps), sum = 9809494115
clamp::naive     0.374sec(273570151cps), sum = 9809494115
clamp::lamerok   0.374sec(273695267cps), sum = 9809494115
clamp::webkit    0.148sec(693060063cps), sum = 9809494115
clamp::webkitv2  0.148sec(689713919cps), sum = 9809494115
clamp::tsar      0.267sec(383867045cps), sum = 9809494115
clamp::bytemux   0.147sec(694408103cps), sum = 9809494115
clamp::bait      0.149sec(688128225cps), sum = 9809494115

g++ -O3 -march=native -fwhole-program -funroll-all-loops
clamp::std       0.119sec(859837415cps), sum = 9807621259
clamp::ffmpeg    0.118sec(864413807cps), sum = 9807621259
clamp::naive     0.340sec(300990070cps), sum = 9807621259
clamp::lamerok   0.345sec(296411503cps), sum = 9807621259
clamp::webkit    0.161sec(635606224cps), sum = 9807621259
clamp::webkitv2  0.176sec(582843715cps), sum = 9807621259
clamp::tsar      0.119sec(857329122cps), sum = 9807621259
clamp::bytemux   0.124sec(828150036cps), sum = 9807621259
clamp::bait      0.148sec(690736415cps), sum = 9807621259

clang++ -O3 -march=native -fwhole-program -funroll-all-loops
clamp::std       0.148sec(692023062cps), sum = 9809494115
clamp::ffmpeg    0.125sec(820128654cps), sum = 9809494115
clamp::naive     0.375sec(272813421cps), sum = 9809494115
clamp::lamerok   0.375sec(273070838cps), sum = 9809494115
clamp::webkit    0.149sec(689151123cps), sum = 9809494115
clamp::webkitv2  0.148sec(693277660cps), sum = 9809494115
clamp::tsar      0.267sec(383173580cps), sum = 9809494115
clamp::bytemux   0.148sec(692600548cps), sum = 9809494115
clamp::bait      0.148sec(691883640cps), sum = 9809494115

g++ -O3 -march=native -fwhole-program -fno-tree-vectorize
clamp::std       0.125sec(818912993cps), sum = 9807621259
clamp::ffmpeg    0.125sec(820864239cps), sum = 9807621259
clamp::naive     0.387sec(264635427cps), sum = 9807621259
clamp::lamerok   0.384sec(266779650cps), sum = 9807621259
clamp::webkit    0.175sec(584473000cps), sum = 9807621259
clamp::webkitv2  0.186sec(551176186cps), sum = 9807621259
clamp::tsar      0.124sec(822982427cps), sum = 9807621259
clamp::bytemux   0.129sec(792407301cps), sum = 9807621259
clamp::bait      0.149sec(687230440cps), sum = 9807621259

clang++ -O3 -march=native -fwhole-program -fno-tree-vectorize
clamp::std       0.148sec(693847242cps), sum = 9809494115
clamp::ffmpeg    0.124sec(823391206cps), sum = 9809494115
clamp::naive     0.375sec(273060145cps), sum = 9809494115
clamp::lamerok   0.374sec(273760572cps), sum = 9809494115
clamp::webkit    0.148sec(692733385cps), sum = 9809494115
clamp::webkitv2  0.148sec(693276383cps), sum = 9809494115
clamp::tsar      0.267sec(383581568cps), sum = 9809494115
clamp::bytemux   0.148sec(693854882cps), sum = 9809494115
clamp::bait      0.148sec(693377556cps), sum = 9809494115

g++ -O3 -march=native -fwhole-program -fno-tree-vectorize -fno-unroll-loops
clamp::std       0.124sec(823902373cps), sum = 9807621259
clamp::ffmpeg    0.124sec(824040857cps), sum = 9807621259
clamp::naive     0.385sec(266021970cps), sum = 9807621259
clamp::lamerok   0.384sec(266628195cps), sum = 9807621259
clamp::webkit    0.198sec(516485573cps), sum = 9807621259
clamp::webkitv2  0.235sec(435067484cps), sum = 9807621259
clamp::tsar      0.124sec(823299478cps), sum = 9807621259
clamp::bytemux   0.128sec(798254429cps), sum = 9807621259
clamp::bait      0.149sec(688806490cps), sum = 9807621259

clang++ -O3 -march=native -fwhole-program -fno-tree-vectorize -fno-unroll-loops
clamp::std       0.148sec(690559736cps), sum = 9809494115
clamp::ffmpeg    0.125sec(818653584cps), sum = 9809494115
clamp::naive     0.380sec(269759692cps), sum = 9809494115
clamp::lamerok   0.377sec(271850082cps), sum = 9809494115
clamp::webkit    0.150sec(684045072cps), sum = 9809494115
clamp::webkitv2  0.149sec(685757375cps), sum = 9809494115
clamp::tsar      0.269sec(381055410cps), sum = 9809494115
clamp::bytemux   0.152sec(673951379cps), sum = 9809494115
clamp::bait      0.149sec(687494375cps), sum = 9809494115

g++ -O3 -march=native -fwhole-program -fno-tree-vectorize -funroll-all-loops
clamp::std       0.120sec(856522365cps), sum = 9807621259
clamp::ffmpeg    0.119sec(860148750cps), sum = 9807621259
clamp::naive     0.346sec(295957090cps), sum = 9807621259
clamp::lamerok   0.346sec(295848278cps), sum = 9807621259
clamp::webkit    0.163sec(627282667cps), sum = 9807621259
clamp::webkitv2  0.177sec(578095437cps), sum = 9807621259
clamp::tsar      0.123sec(833794634cps), sum = 9807621259
clamp::bytemux   0.119sec(859543369cps), sum = 9807621259
clamp::bait      0.149sec(688182897cps), sum = 9807621259

clang++ -O3 -march=native -fwhole-program -fno-tree-vectorize -funroll-all-loops
clamp::std       0.149sec(687530985cps), sum = 9809494115
clamp::ffmpeg    0.125sec(818404687cps), sum = 9809494115
clamp::naive     0.375sec(273252739cps), sum = 9809494115
clamp::lamerok   0.376sec(272109039cps), sum = 9809494115
clamp::webkit    0.148sec(692489552cps), sum = 9809494115
clamp::webkitv2  0.148sec(693071799cps), sum = 9809494115
clamp::tsar      0.267sec(383431654cps), sum = 9809494115
clamp::bytemux   0.148sec(693442612cps), sum = 9809494115
clamp::bait      0.148sec(693473780cps), sum = 9809494115


  no_inline uint8_t bytemux(int32_t c) {
    uint32_t neg = ~0u * (c < 0);
    uint32_t big = ~0u * (c > 255);
    
    return (c & ~neg & ~big) | (~0u & ~neg & big);
  }
  
  no_inline uint8_t bait(int32_t c) {
    return ((uint8_t)c | 0xff00u) >> ((c < 0) + (c > 255u)) * 8;
  }

NishiragiShintaro
()
Ответ на: комментарий от NishiragiShintaro
g++ -O3 -march=native -fwhole-program -Dno_inline=inline -fno-tree-vectorize
clamp::std       0.086sec(1193973187cps), sum = 9807621259
clamp::ffmpeg    0.217sec(472381653cps), sum = 9807621259
clamp::naive     0.319sec(321253115cps), sum = 9807621259
clamp::lamerok   0.319sec(321352937cps), sum = 9807621259
clamp::webkit    0.089sec(1153118494cps), sum = 9807621259
clamp::webkitv2  0.102sec(1000938731cps), sum = 9807621259
clamp::tsar      0.200sec(511948953cps), sum = 9807621259
clamp::bytemux   0.114sec(898643823cps), sum = 9807621259
clamp::bait      0.125sec(821314694cps), sum = 9807621259

clang++ -O3 -march=native -fwhole-program -Dno_inline=inline -fno-tree-vectorize
clamp::std       0.066sec(1555589901cps), sum = 9809494115
clamp::ffmpeg    0.074sec(1390821547cps), sum = 9809494115
clamp::naive     0.066sec(1558511901cps), sum = 9809494115
clamp::lamerok   0.065sec(1573600370cps), sum = 9809494115
clamp::webkit    0.077sec(1327697981cps), sum = 9809494115
clamp::webkitv2  0.077sec(1332888290cps), sum = 9809494115
clamp::tsar      0.199sec(514396723cps), sum = 9809494115
clamp::bytemux   0.067sec(1535203129cps), sum = 9809494115
clamp::bait      0.091sec(1124539387cps), sum = 9809494115

g++ -O3 -march=native -fwhole-program -Dno_inline=inline -fno-tree-vectorize fno-unroll-loops
clamp::std       0.066sec(1560450503cps), sum = 9809494115
clamp::ffmpeg    0.075sec(1365660527cps), sum = 9809494115
clamp::naive     0.066sec(1548261526cps), sum = 9809494115
clamp::lamerok   0.066sec(1543024193cps), sum = 9809494115
clamp::webkit    0.078sec(1312562476cps), sum = 9809494115
clamp::webkitv2  0.077sec(1326669462cps), sum = 9809494115
clamp::tsar      0.199sec(514105836cps), sum = 9809494115
clamp::bytemux   0.066sec(1558596943cps), sum = 9809494115
clamp::bait      0.090sec(1133790325cps), sum = 9809494115

clang++ -O3 -march=native -fwhole-program -Dno_inline=inline -fno-tree-vectorize fno-unroll-loops
clamp::std       0.065sec(1583715543cps), sum = 9809494115
clamp::ffmpeg    0.073sec(1394609705cps), sum = 9809494115
clamp::naive     0.069sec(1492784355cps), sum = 9809494115
clamp::lamerok   0.066sec(1544820834cps), sum = 9809494115
clamp::webkit    0.078sec(1307000856cps), sum = 9809494115
clamp::webkitv2  0.077sec(1337756045cps), sum = 9809494115
clamp::tsar      0.199sec(514028131cps), sum = 9809494115
clamp::bytemux   0.065sec(1565113952cps), sum = 9809494115
clamp::bait      0.089sec(1146100569cps), sum = 9809494115

g++ -O3 -march=native -fwhole-program -Dno_inline=inline -fno-tree-vectorize -funroll-all-loops
clamp::std       0.073sec(1407008416cps), sum = 9807621259
clamp::ffmpeg    0.207sec(495599636cps), sum = 9807621259
clamp::naive     0.281sec(364869444cps), sum = 9807621259
clamp::lamerok   0.280sec(366264261cps), sum = 9807621259
clamp::webkit    0.071sec(1443184008cps), sum = 9807621259
clamp::webkitv2  0.083sec(1239573330cps), sum = 9807621259
clamp::tsar      0.199sec(515281824cps), sum = 9807621259
clamp::bytemux   0.103sec(990573167cps), sum = 9807621259
clamp::bait      0.119sec(859411867cps), sum = 9807621259

clang++ -O3 -march=native -fwhole-program -Dno_inline=inline -fno-tree-vectorize -funroll-all-loops
clamp::std       0.065sec(1580536678cps), sum = 9809494115
clamp::ffmpeg    0.072sec(1413970525cps), sum = 9809494115
clamp::naive     0.064sec(1608533016cps), sum = 9809494115
clamp::lamerok   0.068sec(1511760299cps), sum = 9809494115
clamp::webkit    0.076sec(1340845911cps), sum = 9809494115
clamp::webkitv2  0.077sec(1333170627cps), sum = 9809494115
clamp::tsar      0.199sec(515396478cps), sum = 9809494115
clamp::bytemux   0.074sec(1390905728cps), sum = 9809494115
clamp::bait      0.094sec(1091029712cps), sum = 9809494115

Как я уже говорил - более адекватные результаты стоят в начале, где нет инлайна.

NishiragiShintaro
()
Ответ на: комментарий от anonymous
g++ -O3 -march=native -fwhole-program
clamp::bytemux           0.136sec(751317154cps), sum = 9807621259
clamp::bytemuxv2         0.125sec(819788161cps), sum = 9807621259

clang++ -O3 -march=native -fwhole-program
clamp::bytemux           0.151sec(678867515cps), sum = 9809494115
clamp::bytemuxv2         0.124sec(827955764cps), sum = 9809494115

g++ -O3 -march=native -fwhole-program -funroll-all-loops
clamp::bytemux           0.119sec(860969877cps), sum = 9807621259
clamp::bytemuxv2         0.118sec(866266292cps), sum = 9807621259

clang++ -O3 -march=native -fwhole-program -funroll-all-loops
clamp::bytemux           0.153sec(670353892cps), sum = 9809494115
clamp::bytemuxv2         0.124sec(824851725cps), sum = 9809494115

g++ -O3 -march=native -fwhole-program -fno-tree-vectorize
clamp::bytemux           0.148sec(691318578cps), sum = 9807621259
clamp::bytemuxv2         0.105sec(970918755cps), sum = 9807621259

clang++ -O3 -march=native -fwhole-program -fno-tree-vectorize
clamp::bytemux           0.147sec(694468590cps), sum = 9809494115
clamp::bytemuxv2         0.124sec(827581226cps), sum = 9809494115

g++ -O3 -march=native -fwhole-program -fno-tree-vectorize -fno-unroll-loops
clamp::bytemux           0.150sec(684143006cps), sum = 9807621259
clamp::bytemuxv2         0.106sec(967090952cps), sum = 9807621259

clang++ -O3 -march=native -fwhole-program -fno-tree-vectorize -fno-unroll-loops
clamp::bytemux           0.148sec(693644661cps), sum = 9809494115
clamp::bytemuxv2         0.129sec(795139585cps), sum = 9809494115

g++ -O3 -march=native -fwhole-program -fno-tree-vectorize -funroll-all-loops
clamp::bytemux           0.122sec(841602025cps), sum = 9807621259
clamp::bytemuxv2         0.120sec(855144529cps), sum = 9807621259

clang++ -O3 -march=native -fwhole-program -fno-tree-vectorize -funroll-all-loops
clamp::bytemux           0.148sec(693051681cps), sum = 9809494115
clamp::bytemuxv2         0.124sec(825222972cps), sum = 9809494115

g++ -O3 -march=native -fwhole-program -Dno_inline=inline -fno-tree-vectorize
clamp::bytemux           0.114sec(895287043cps), sum = 9807621259
clamp::bytemuxv2         0.089sec(1156613093cps), sum = 9807621259

clang++ -O3 -march=native -fwhole-program -Dno_inline=inline -fno-tree-vectorize
clamp::bytemux           0.066sec(1556054090cps), sum = 9809494115
clamp::bytemuxv2         0.065sec(1576629789cps), sum = 9809494115

g++ -O3 -march=native -fwhole-program -Dno_inline=inline -fno-tree-vectorize fno-unroll-loops
clamp::bytemux           0.066sec(1549829406cps), sum = 9809494115
clamp::bytemuxv2         0.065sec(1569948920cps), sum = 9809494115

clang++ -O3 -march=native -fwhole-program -Dno_inline=inline -fno-tree-vectorize fno-unroll-loops
clamp::bytemux           0.069sec(1492448059cps), sum = 9809494115
clamp::bytemuxv2         0.067sec(1536920784cps), sum = 9809494115

g++ -O3 -march=native -fwhole-program -Dno_inline=inline -fno-tree-vectorize -funroll-all-loops
clamp::bytemux           0.101sec(1012751500cps), sum = 9807621259
clamp::bytemuxv2         0.077sec(1327019760cps), sum = 9807621259

clang++ -O3 -march=native -fwhole-program -Dno_inline=inline -fno-tree-vectorize -funroll-all-loops
clamp::bytemux           0.066sec(1546320288cps), sum = 9809494115
clamp::bytemuxv2         0.066sec(1550023817cps), sum = 9809494115

NishiragiShintaro
()
Ответ на: комментарий от anonymous

Ну да, в каких-то случаях даже лучше.

Я там сделал, чтобы можно было удобно читать функции: https://godbolt.org/z/OTDW9z

Кстати, у меня локально эту функцию гцц собирает так:

bytemuxv2:
.LFB4714:
	.cfi_startproc
	xorl	%eax, %eax
	cmpl	$255, %edi
	setg	%al
	negl	%eax
	orl	%edi, %eax
	shrl	$31, %edi
	decl	%edi
	andl	%edi, %eax
	ret

Кстати, я эпично обосрался с gcc. Я забыл про stack-protector, который врублен в генте по умолчанию.

g++ -O3 -march=native -fwhole-program
clamp::webkit            0.179sec(572313034cps), sum = 9807621259
clamp::webkitv2          0.202sec(506932562cps), sum = 9807621259

g++ -O3 -march=native -fwhole-program -funroll-all-loops
clamp::webkit            0.162sec(632232018cps), sum = 9807621259
clamp::webkitv2          0.176sec(581102006cps), sum = 9807621259

g++ -O3 -march=native -fwhole-program -funroll-all-loops -fno-stack-protector
clamp::webkit            0.120sec(850249534cps), sum = 9807621259
clamp::webkitv2          0.122sec(838154309cps), sum = 9807621259

g++ -O3 -march=native -fwhole-program -fno-stack-protector
clamp::webkit            0.129sec(794016139cps), sum = 9807621259
clamp::webkitv2          0.136sec(753298328cps), sum = 9807621259

webkit пострадал от моей тупости.

NishiragiShintaro
()
Ответ на: комментарий от anonymous

не UB (для особо дотошных - не IDB)

не Java (для особо дотошных - не Scheme Lisp)

anonymous
()
Ответ на: комментарий от anonymous

Вариант «мультиплексор».

Написал тупой каскад мультиплексоров, или просто каскад тернарных операторов ?: (mux <-> :?)

template <class T> T mux(bool s, T a, T b) {
    T one = ~(T());
    T ss = one * s;
    return (a & ss) | (b & ~ss);
}                                                                                                                                                                         

unsigned char clampMux(int c) {
    return mux(c < 0, 0, mux(c > 255, 255, c));
}

clang++ -O2 распознал, что это :?, и выдал код с условным переходом. g++ -O2 выдал почти такой же плохой код, что у тебя.

anonymous
()
Ответ на: комментарий от anonymous

Написал тупой каскад мультиплексоров, или просто каскад тернарных операторов ?

4-to-1 мультиплексор.

anonymous
()
Ответ на: комментарий от anonymous

4-to-1 мультиплексор.

Cлишком сложно для меня, я тупой. Все равно, если потом упрощать, то получиться одно и то же. А каскад проще упростить.

PS. Слишком много слов с корнем просто.

anonymous
()
Ответ на: комментарий от anonymous

А каскад проще упростить.

Разве? Там нужен полный «инлайн», чтобы упростилось. Проще тогда сразу формулу для 4-to-1 использовать.

anonymous
()
Ответ на: комментарий от anonymous

У меня каскад неполный. Хотя, надо бы сравнить. Возможно, то что уже делал, кажется проще. Но не хочу, лень.

anonymous
()
Ответ на: комментарий от anonymous

Нене, я тупой, это не ко мне. Clang и так выдает код из 7 асм команд против 14 от gcc. Но количество команд - это не показатель оптимальности по скорости.

anonymous
()
Ответ на: комментарий от anonymous

У меня тоже формула 4-to-1 неполная, только половина её.

Сдаюсь, ты победил. Лень проверять.

anonymous
()

А можно вопрос

В треде по сути обсуждается, что если foocc 1.4.88 пощекотать за ушком, то он крякнет, а если barlang 6.6.6 потянуть за палец, то он ну вы понели. Собственно вопрос: а это имеет какие-то основания в плане предсказуемости (код -> поведение)? Или это просто мам смотри как мы с Машей в этом году друг друга понимаем?

Способности участников треда к созданию эффективных программ под сомнение конечно не ставятся, но не является ли это всё snakeoil, если завтра компилятор родит другой набор инструкций, и все предположения о том, что он там генерит, пойдут по лесу. Ведь вы здесь программируете side-effect, а не intent*, и компилятору неоткуда узнать последний. Это так или нет?

* будь то константное время или скорость на определенном характере данных.

anonymous
()
Ответ на: А можно вопрос от anonymous

Ты повторяешь нелепую методичку про «а вдруг завтра другой набор», «вдруг завтра другой процессор».

Всё это глупости по многим причинам. Первое - всё это работает по одним и тем же принципам и если какой-то подход эффективнее, то он будет везде эффективен. Допустим, ветвления всегда будут говно. Придумай хоть какую архитектуру, хоть какой процессор - они будут говно.

Второе - на компилятор всем насрать. Если мне нужна будет эффективная реализация - я напишу её руками. А даже если не напишу - я могу задетектить регрессию.

Оптимальная реализация будет оптимальной, т.к. более оптимальную никто не придумал, а даже если придумает - вряд ли она появится в компиляторе. А если появится - я так же могу поймать этот эффект. На самом деле она там никогда не появится, потому что все эти бенчмарки - это говно, а все эти реализации - говно.

Те, которые не используют cmov - являются базой, которую можно использовать в хороших реализациях.

По поводу рассуждения на тему «почему вы проверяете код из-под компилятора». Всё очень просто - языки не предоставляют конструкцию cmov и компилятор должен её ставить сам. Именно в этом проблема.

NishiragiShintaro
()
Ответ на: комментарий от NishiragiShintaro

у тебя дизлексия

Те, которые не используют cmov - являются базой, которую можно использовать в хороших реализациях.

языки не предоставляют конструкцию cmov и компилятор должен её ставить сам. Именно в этом проблема.

ты уж определись: cmov — это хорошо или плохо.

когда-то было такое мнение:

CMOV is a piece of CRAP for most things, exactly because it serializes three streams of data: the two inputs, and the conditional. (с) Linus Torvalds

anonymous
()
Ответ на: А можно вопрос от anonymous

код из оп-поста правильно решает вполне конкретную задачу: выполнение за константное время при любых входных данных.

предложенные здесь портянки — это дрочка вприсядку на производительность фрагмента из десятка инструкций, которая, конечно, не имеет никакой практической ценности и никаких гарантий при смене компилятора.

anonymous
()
Ответ на: у тебя дизлексия от anonymous

ты уж определись: cmov — это хорошо или плохо.

Ламерок, ты действительно считаешь, что ты можешь найти какие-то ошибки в моих рассуждениях?

Я тебе задам вопрос, откуда твоя шизофрения вообще сгенерировала, что cmov это хорошо, либо не хорошо? Тебе лишь сообщили почему был написан разный код.

CMOV is a piece of CRAP for most things, exactly because it serializes three streams of data: the two inputs, and the conditional. (с) Linus Torvalds

Это какие-то его локальные переживания и какие там три потока у него родились - мне неведомо. Да и в каком контексте он это говорил - ты не сообщил. Может он говорил это в контексте какого-нибудь си и тому подобного.

Хотя x = (cond) ? a : b; работает так же. К том уже никаких условий тут нет - тут есть результат операции сравнения, если просто. Это как говорить, что memcmp делает какое-то условие.

NishiragiShintaro
()
Ответ на: комментарий от anonymous

код из оп-поста правильно решает вполне конкретную задачу: выполнение за константное время при любых входных данных.

Иди чини методичку - проблема не в том, что оно там решает, а как.

предложенные здесь портянки — это дрочка вприсядку на производительность фрагмента из десятка инструкций, которая, конечно, не имеет никакой практической ценности и никаких гарантий при смене компилятора.

Ну, если тебе, домохозяйке, это непонятно и тебя на это триггерит - иди мой полы, зачем сюда пришел?

Про смену компилятора - херня. Зачем домохозяйка кукарекает о том, в чём нихрена не понимает?

NishiragiShintaro
()
Ответ на: комментарий от NishiragiShintaro

ты можешь найти какие-то ошибки в моих рассуждениях?

для этого нужно наличие рассуждений. пока ты настолько плохо умеешь в русский, что понять тебя невозможно. вот и уточняю:

cmov — это хорошо или плохо.

Это какие-то его локальные переживания

т.е., по-твоему, всё-таки хорошо.

какие там три потока у него родились

в английский тоже плохо.

контекст можешь взять в эпичном lkml-треде «kernel + gcc 4.1 = several problems» где-то в начале 2007 года.

там и про смену, компилятора, да. но в это говно я мокну тебя в следующем ответе.

anonymous
()
Ответ на: комментарий от NishiragiShintaro

проблема не в том, что оно там решает, а как

видишь проблему? назови её.

Про смену компилятора - херня

взял твою портянку:

uint8_t clampb(int32_t c) {
  uint32_t uc = c;  
  uint32_t res = 255 * !(c < 0);
  if(uc < 255) return uc;
  return res;
}

gcc-8.3 -O2

        mov     eax, edi
        sar     eax, 31
        cmp     edi, 254
        not     eax
        cmovbe  eax, edi
        ret

clang-8.0.0 -O2

        mov     eax, edi
        cmp     edi, 254
        jbe     .LBB0_2
        shr     eax, 31
        or      al, -2
        add     al, 1
.LBB0_2:
        ret

anonymous
()
Ответ на: комментарий от anonymous

код из оп-поста правильно решает вполне конкретную задачу: выполнение за константное время при любых входных данных.

Код из оп-поста как минимум имеет implementation-defined behaivor, то есть это похуже от того что там решит наоптимизировать конкретный компилятор.
Также, почему компилятор не имеет права «оптимизировать» обращение к стеку? Он вполне может вместо этого напихать обращение к регистрам с условными переходами. И коту под хвост попытка избавления от условных переходов, как попытка защиты от тайминг-атак.

anonymous
()
Ответ на: комментарий от anonymous

для этого нужно наличие рассуждений. пока ты настолько плохо умеешь в русский, что понять тебя невозможно. вот и уточняю:

Ну ты просто слаб и не обладаешь контекстом. Давай объясню попроще. Все подобные вычисления параллелятся, в том числе и на уровне тех же симдов. На их фоне тебе будет наиболее понятно. Т.е. код на логике - векторизуется - на cmove нет. Вернее векторизовать то можно через маски, но это дополнительный оверхед.

т.е., по-твоему, всё-таки хорошо.

Для случай бич-логики да. Для вычислений - нет.

в английский тоже плохо.

Опять вскукареки нелепые без каких-либо обоснований.

контекст можешь взять в эпичном lkml-треде «kernel + gcc 4.1 = several problems» где-то в начале 2007 года.

Я не собираюсь за тебя гуглить, читать. Мне как-то насрать. Если ты приводишь цитату и строишь на ней что-то/спрашиваешь кого-то - сообщай о контексте.

там и про смену, компилятора, да. но в это говно я мокну тебя в следующем ответе.

Макнушь ты свою рожу, в собственно дерьмо.

NishiragiShintaro
()
Ответ на: комментарий от anonymous

видишь проблему? назови её.

Проблема была продекларирована вначале. Читай тему.

взял твою портянку:

И сразу обосрался, изваляв свою рожу в дерьме. Потому что ты кукарекал не про мою портянку.

O2

С этим идёшь на помойку.

Самое интересное, что бездарный дошколёнок пытается мне что-то кукарекать. Хотя именно я написал этот код, я его написал с определённой целью, а так же я знаю где и как он собирается. И этот дошколёнок действительно считает, что он спастив портянку куда-то - что-то мне сообщи нового?

Самое интересное, что этому школотрону я уже всё объяснил. Про то, что мне насрать на какие-то его маня-компиляторы, мне насрать на подобный код, мне насрать на его резульататы, потому что в подобном виде я его не использую.

Вообщем, мне лень одно и тоже писать школотрону, который дёргает куски из фразы и игнорирует уже существующий ответ на его потуги нелепые.

NishiragiShintaro
()
Ответ на: комментарий от anonymous

Код из оп-поста как минимум имеет implementation-defined behaivor

тебя обманули.

[basic.fundamental]
4
Unsigned integers, declared unsigned, shall obey the laws of arithmetic modulo 2 n where n is the number
of bits in the value representation of that particular size of integer.

почему компилятор не имеет права «оптимизировать» обращение к стеку?

здесь ты прав: теоретически имеет. я не знаю как нужно упороться чтобы из ast без ветвлений сгенерировать «оптимизированное» ast с ветвлениями, но экспертом в веществах не являюсь. думаю, это можно починить добавлением volatile в объявление buff.

anonymous
()
Ответ на: комментарий от NishiragiShintaro

подобные вычисления параллелятся

куда тебя понесло... проще вот как. этот код:

if (a < b) {
    c = 0;
}
с cmov работает хуже чем без него. a, b и с — те самые 3 «потока», про которые ты ничего не понял в цитате.

Для случай бич-логики да. Для вычислений - нет.

виляешь жопой.

Опять вскукареки нелепые без каких-либо обоснований.

ты не смог перевести одно простое предложение. какие здесь ещё обоснования нужны?

anonymous
()
Ответ на: комментарий от Deleted

Так стоило выбрать царский ник

Царю не нужно подписываться Царём. После первой реплики всем и так это станет понятно, кто это пишет.

а не это анимуфажное странывосходящегосолнца говно

Всё равно растосектанты забанят.

crutch_master ★★★★★
()
Ответ на: комментарий от anonymous

с cmov работает хуже чем без него. a, b и с — те самые 3 «потока», про которые ты ничего не понял в цитате.

Полная херня. Обоснования потугам «хуже работает».

виляешь жопой.

Дошколятинка убогая - побежала обосновывать эти потуги нелепые.

ты не смог перевести одно простое предложение. какие здесь ещё обоснования нужны?

Побежала обосновывать, что я там что-то не перевёл.

NishiragiShintaro
()
Ответ на: комментарий от anonymous

Код из оп-поста как минимум имеет implementation-defined behaivor

тебя обманули.

Поехали по новой Объясните сишную магию (комментарий)

А теперь дай побитовое представление числа "-1". Заметь, разрешается прямой, обратный и дополнительный код, а возможно еще какие-нибудь другие (позиционные) двоичные системы.

как ... из ast без ветвлений сгенерировать «оптимизированное» ast с ветвлениями

Как только покажешь, что !!(expr) - это не ветвление. Также, в общем случае, каст тоже может быть ветвлением.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.