The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]



Индекс форумов
Составление сообщения

Исходное сообщение
"Дэниэл Бернштейн выступил с инициативой создания Си-компилят..."
Отправлено Нимано, 23-Дек-15 04:35 
>>  И что, это уже не костыль?
> Нет.

Ну-ну. Особенно приведенный вами вами код.
> __asm__ ("" : "=r" (var) : "" (var))

соберите с ним ядро и наслаждайтесь скоростью (намек: шланг хоть ругается на "invalid constraint", а гцц "кушает" и не обляпывается, генерируя


cmp     rdx, 16
        jne     .L5
        ret

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

>  строгим упорядочиванием составляющих эту функцию команд.

Гм, намекну:
Берем оригинальный код и делаем так:


    unsigned long neq = 0;
    unsigned long tmp1, tmp2;
#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
    if (sizeof(unsigned long) == 8) {
        tmp1 = *(unsigned long *)(a)   ^ *(unsigned long *)(b);
        tmp2 = *(unsigned long *)(a + 8) ^ *(unsigned long *)(b + 8);
        neq |= tmp1;
        OPTIMIZER_HIDE_VAR(neq);        
        neq |= tmp2;
        OPTIMIZER_HIDE_VAR(neq);

Для gcc49 -O2 -DCONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS на выходе у нас будет:

        cmp     rdx, 16
        jne     .L5
        mov     rdx, QWORD PTR [rdi+8]
        xor     rdx, QWORD PTR [rsi+8]
        mov     rax, QWORD PTR [rdi]
        xor     rax, QWORD PTR [rsi]
        or      rax, rdx
        ret

Вот это вам выдаст шланг37 -O2
# BB#1:                                 # %sw.bb
        mov     rax, qword ptr [rsi]
        mov     rcx, qword ptr [rsi + 8]
        xor     rax, qword ptr [rdi]
        xor     rcx, qword ptr [rdi + 8]
        #APP
        #NO_APP
        or      rax, rcx
        #APP
        #NO_APP
        pop     rbp
        ret

ВНЕЗАПНО – и там и там – совершенно неотличимо от оригинала!1
Делаем такой же фокус для ветки else:

        movzx   edx, BYTE PTR [rdi+1]
        movzx   eax, BYTE PTR [rdi]
        xor     dl, BYTE PTR [rsi+1]
        xor     al, BYTE PTR [rsi]
        movzx   edx, dl
        movzx   eax, al
        or      rax, rdx

Опять же, как и ожидалось,  сгенерированный код одинаков в обоих случаях, но и не соответствует порядку "составляющих эту функцию команд".
Да и чего ему соответствовать, когда костыляние OPTIMIZER_HIDE_VAR(var) не дает убрать лишние OR (и заодно "закрепляет" их очередность, да, хотя от этого мало что меняется – вариации в тайминге будут полюбому наамного больше зависить от кэшмисов).


> Указание — единственный эффект этой конструкции.
> Эта вставка вводит фиктивную зависимость по данным между обращениями к neq.

Нет.


neq = neq | expr = (a ^ b);
OPTIMIZER_HIDE_VAR(neq);
neq = neq | expr2 = (a2 ^ b2);

ничто не мешает компилятору вынести expr1,2 и т.д отдельно
Вот это вводит фиктивную зависимость по данным:
 tmp = a ^ b;
OPTIMIZER_HIDE_VAR(neq);
OPTIMIZER_HIDE_VAR(tmp);
neq |= tmp;

Только она там нужна, как рыбе зонтик, ибо еще раз повторюсь – разброс в тайминге из-за кэша будет куда выше, чем из-за очередности выполнения (X)OR r, mem .
А вот преждевременное "or foo,bar; jnz quit" после сравнения первого байта – будет, как бы, очень заметно.

> правильно поняли часть её назначения: гарантировать, что сгенерированный компилятором
> код будет в точности, без изъятий соответствовать коду, написанному на C.

Там, наверху, можно посмотреть на "соответствование".

> Это вторая часть решения задачи обеспечения постоянного времени выполнения функции.

На сферическо-вакуумных суперскалярах – вполне.  А так, см. тайминги для xor/or r/m и "сколько стоит кэшмисс".


> Однако ваше опасение справедливо лишь для случаев, когда значения аргументов a и
> b, а также константные смещения относительно них известны компилятору во время
> компиляции.

Компилятору достаточно того, что любое значение neq !=0 возвращает в итоге единицу.
Это, и зависимость neq от (a xor b) позволяет вообще выкинуть neq и сразу проверять результат XORа.

> Совершенно верно, это фиктивная зависимость по данным. Но предотвращает она не dead
> code elimination (тогда здесь было бы достаточно спецификатора volatile при объявлении
> neq), а переупорядочивание выражений друг относительно друга.

Хоть в ядро бы глянули, что там по этому поводу писали и чего опасались:
https://github.com/torvalds/linux/commit/6bf37e5aa90f18baf5a...
> crypto_memneq is declared noinline, placed in its own source file,
> and compiled with optimizations that might increase code size disabled
> ("Os") because a smart compiler (or LTO) might notice that the return
> value is always compared against zero/nonzero, and might then
> reintroduce the same early-return optimization that we are trying to
> avoid.

https://github.com/torvalds/linux/commit/fe8c8a126806fea4465...

> Instead of disabling compiler optimizations, use a dummy inline assembly
> (based on RELOC_HIDE) to block the problematic kinds of optimization,
> The dummy inline assembly is added after every OR, and has the
> accumulator variable as its input and output. The compiler is forced to
> assume that the dummy inline assembly could both depend on the
> accumulator variable and change the accumulator variable, so it is
> forced to compute the value correctly before the inline assembly, and
> cannot assume anything about its value after the inline assembly.

Хотя, о чем это я – этож опеннет.

> gcc или clang никогда не научатся разбирать содержимое ассемблерных вставок by design.
> Это контракт. Вопрос не имеет смысла.

В вашей вселенной – возможно и контракт. В моей об этом речи нет:
https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Assembl...
Да и ваш "пример" с
>  __asm__ ("" : "=r" (var) : "" (var))

отлично показал "надежность" этого "контракта".


 

Ваше сообщение
Имя*:
EMail:
Для отправки ответов на email укажите знак ! перед адресом, например, !user@host.ru (!! - не показывать email).
Более тонкая настройка отправки ответов производится в профиле зарегистрированного участника форума.
Заголовок*:
Сообщение*:
 
При общении не допускается: неуважительное отношение к собеседнику, хамство, унизительное обращение, ненормативная лексика, переход на личности, агрессивное поведение, обесценивание собеседника, провоцирование флейма голословными и заведомо ложными заявлениями. Не отвечайте на сообщения, явно нарушающие правила - удаляются не только сами нарушения, но и все ответы на них. Лог модерирования.



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру