Умный указатель создает неэффективный скомпилированный кодC++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Умный указатель создает неэффективный скомпилированный код

Сообщение Anonymous »

Я реализую BST и думаю, что было бы неплохо использовать unique_ptr для представления владения дочерним узлом. Однако я обнаружил, что интеллектуальные указатели заставляют компилятор отдавать предпочтение ветвлению вместо кода без ветвлений (а именно cmov). Я использую g++-13 для компиляции и Ubuntu 24.04.1 LTS. Я использую тернарный оператор для поддержки кода без ветвей, но безрезультатно. Вот простой прототип.

Код: Выделить всё

#include 
#include 
struct node {
int val;
node* left_child;
node* right_child;
};

struct smart_node {
int val;
std::unique_ptr left_child;
std::unique_ptr right_child;
};

node*
__attribute__((noinline))
raw(node* root, int key) {
node* prev = root;
node* curr = prev -> left_child;
while (curr != nullptr) {
prev = curr;
bool comp = key < (curr -> val);
curr = comp ? curr -> left_child : curr -> right_child;
}
return prev;
}

smart_node*
__attribute__((noinline))
smart(std::unique_ptr root, int key) {
smart_node* prev = root.get();
smart_node* curr = prev -> left_child.get();
while (curr != nullptr) {
prev = curr;
bool comp = key < (curr -> val);
curr = comp ? curr -> left_child.get() : curr -> right_child.get();
}
return prev;
}

int main() {
auto last1 = raw(nullptr, 1);
auto last2 = smart(std::make_unique(), 1);
std::cout  val  val;
}

Ниже приведен ассемблерный код цикла в необработанном виде.

Код: Выделить всё

    1310:   48 89 c2                mov    %rax,%rdx
1313:   48 8b 42 10             mov    0x10(%rdx),%rax
1317:   3b 32                   cmp    (%rdx),%esi
1319:   48 0f 4c 42 08          cmovl  0x8(%rdx),%rax
131e:   48 85 c0                test   %rax,%rax
1321:   75 ed                   jne    1310 
Ниже приведен ассемблерный код цикла в smart.

Код: Выделить всё

    1360:   48 8b 50 08             mov    0x8(%rax),%rdx
1364:   48 85 d2                test   %rdx,%rdx
1367:   74 10                   je     1379 
1369:   48 89 d0                mov    %rdx,%rax
136c:   3b 30                   cmp    (%rax),%esi
136e:   7c f0                   jl     1360 
1370:   48 8b 50 10             mov    0x10(%rax),%rdx
1374:   48 85 d2                test   %rdx,%rdx
1377:   75 f0                   jne    1369 
В тесте (вызов 2e6 дерева с 2e6 узлами) код ветвления занимает примерно в 1,4 раза больше времени, чем версия без ветвей. Я использовал RelWithDebInfo, поэтому оптимизация O2 включена. Мой вопрос: как заставить компилятор использовать cmov? Я прочитал этот пост, и мне кажется, что нет чистого способа добиться такого поведения.


Подробнее здесь: https://stackoverflow.com/questions/793 ... piled-code
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Умный указатель создает неэффективный скомпилированный код
    Anonymous » » в форуме C++
    0 Ответы
    8 Просмотры
    Последнее сообщение Anonymous
  • Умный указатель создает неэффективный скомпилированный код
    Anonymous » » в форуме C++
    0 Ответы
    11 Просмотры
    Последнее сообщение Anonymous
  • Умный указатель создает неэффективный скомпилированный код
    Anonymous » » в форуме C++
    0 Ответы
    12 Просмотры
    Последнее сообщение Anonymous
  • Выровненный динамический массив и умный указатель
    Anonymous » » в форуме C++
    0 Ответы
    6 Просмотры
    Последнее сообщение Anonymous
  • C ++ Умный указатель и модель памяти: почему приращения не синхронизируются с уменьшением управляющего блока?
    Anonymous » » в форуме C++
    0 Ответы
    16 Просмотры
    Последнее сообщение Anonymous

Вернуться в «C++»