У меня есть код, указанный ниже:
for(auto i =0;i<k;++i)
printf("%d\n",(va1+va2-(va1-va2))[i]);
где va1
а также va2
два valarray<int>
объекты, k
это размер va1
а также va2
, Я ожидаю, что компилятор оптимизирует printf
линия как:
printf("%d\n", 2*va2[i]);
Но вместо этого компилятор Intel (13.1) и CLang (3.4) не провели такую оптимизацию. Например, компилятор Intel вывел код сборки:
..B1.18: # Preds ..B1.19 ..B1.17
movl (%r14,%r15,4), %r9d #18.42
movl $.L_2__STRING.1, %edi #18.9
movl (%r12,%r15,4), %r8d #18.42
xorl %eax, %eax #18.9
lea (%r9,%r8), %esi #18.9
subl %r8d, %r9d #18.9
subl %r9d, %esi #18.9
..___tag_value_main.18: #18.9
call printf #18.9
..___tag_value_main.19: #
# LOE rbx r12 r13 r14 r15
..B1.19: # Preds ..B1.18
incq %r15 #17.25
cmpq %r13, %r15 #17.21
jl ..B1.18 # Prob 82% #17.21
где r13
хранит значение k
, r14
а также r12
начало памяти va1
а также va2
соответственно. r15
переменная итератора i
, Из кода, что он делает:
load va1[i]
load va2[i]
add va1[i], va2[i] ==> %esi
sub va1[i], va2[i] ==> %r9d
sub %esi, %r9d ==> esi
print %esi
Почему он не оптимизирован (даже с -O3) для
load va2[i]
add va2[i], va2[i] => %esi
print %esi
с оптимизацией глазка? Gcc 4.8.2 выполняет оптимизацию в этом случае, но не может обработать -(va1[i]+va2[i])+(va1[i]-va2[i])
,
Похоже, одной из возможных причин является то, что шаблоны выражений используются в коде, показанном ранее. Теперь вопрос в том, почему компилятор остановил оптимизацию всего за один шаг до совершенства? Как шаблон выражения помешал сделать шаг вперед?
НОТА
Ну, ответ всегда может быть «потому что компилятор не предназначен для такой оптимизации». Но, как я узнал из книги о драконах, компилятор должен выполнять оптимизацию итеративно, пока он не сможет сделать что-то лучше.
Задача ещё не решена.
Других решений пока нет …