Получение GCC/Clang для использования CMOVC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Получение GCC/Clang для использования CMOV

Сообщение Anonymous »

У меня есть простой метки союза значений. Значения могут быть либо int64_ts , либо удвоить . Я выполняю дополнение в этих профсоюзах с предостережением, что, если оба аргумента представляют значение int64_t , то результат также должен иметь значение int64_t .
Вот код:

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

#include
union Value {
int64_t a;
double b;
};

enum Type { DOUBLE, LONG };

// Value + type.
struct TaggedValue {
Type type;
Value value;
};

void add(const TaggedValue& arg1, const TaggedValue& arg2, TaggedValue* out) {
const Type type1 = arg1.type;
const Type type2 = arg2.type;
// If both args are longs then write a long to the output.
if (type1 == LONG && type2 == LONG) {
out->value.a = arg1.value.a + arg2.value.a;
out->type = LONG;
} else {
// Convert argument to a double and add it.
double op1 = type1 == LONG ? (double)arg1.value.a : arg1.value.b; // Why isn't CMOV used?
double op2 = type2 == LONG ? (double)arg2.value.a : arg2.value.b; // Why isn't CMOV used?
out->value.b = op1 + op2;
out->type = DOUBLE;
}
}
< /code>
Вывод GCC AT -O2 здесь < /p>
Прилагается здесь, если ссылка не работает. < /p>
add(TaggedValue const&, TaggedValue const&, TaggedValue*):
cmp DWORD PTR [rdi], 1
sete    al
cmp DWORD PTR [rsi], 1
sete    cl
je  .L17
test    al, al
jne .L18
.L4:
test    cl, cl
movsd   xmm1, QWORD PTR [rdi+8]
jne .L19
.L6:
movsd   xmm0, QWORD PTR [rsi+8]
mov DWORD PTR [rdx], 0
addsd   xmm0, xmm1
movsd   QWORD PTR [rdx+8], xmm0
ret
.L17:
test    al, al
je  .L4
mov rax, QWORD PTR [rdi+8]
add rax, QWORD PTR [rsi+8]
mov DWORD PTR [rdx], 1
mov QWORD PTR [rdx+8], rax
ret
.L18:
cvtsi2sd    xmm1, QWORD PTR [rdi+8]
jmp .L6
.L19:
cvtsi2sd    xmm0, QWORD PTR [rsi+8]
addsd   xmm0, xmm1
mov DWORD PTR [rdx], 0
movsd   QWORD PTR [rdx+8], xmm0
ret
< /code>
Он создал код с большим количеством филиалов. Я знаю, что входные данные довольно случайные, т. Е. Имеют случайную комбинацию int64_t 
s и двойного s. Я бы хотел, чтобы хотя бы преобразование в двойное было сделано с эквивалентом инструкции CMOV . Есть ли способ, которым я могу уговорить GCC для создания этого кода? В идеале я хотел бы запустить некоторый эталон на реальных данных, чтобы увидеть, как код с большим количеством филиалов делает один с одним с меньшим количеством филиалов, но более дорогими инструкциями CMOV . Может оказаться, что код, сгенерированный по умолчанию от GCC, работает лучше, но я хотел бы подтвердить это. Я мог бы внедрить сборку самому, но я бы предпочел не делать. Есть предложения?

Подробнее здесь: https://stackoverflow.com/questions/303 ... o-use-cmov
Ответить

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

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

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

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

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