Как избежать умножения в арифметике указателей?
Если я напишу
int main(int argc, char *argv[])
{
int temp[50][3];
return &temp[argc] - &temp[0];
}
и скомпилировать его с Visual C ++, я вернусь:
009360D0 55 push ebp
009360D1 8B EC mov ebp,esp
009360D3 8B 45 08 mov eax,dword ptr [argc]
009360D6 8D 0C 40 lea ecx,[eax+eax*2]
009360D9 B8 AB AA AA 2A mov eax,2AAAAAABh
009360DE C1 E1 02 shl ecx,2
009360E1 F7 E9 imul ecx
009360E3 D1 FA sar edx,1
009360E5 8B C2 mov eax,edx
009360E7 C1 E8 1F shr eax,1Fh
009360EA 03 C2 add eax,edx
009360EC 5D pop ebp
009360ED C3 ret
Почему я получаюimul
здесь инструкция вместо просто битовых сдвигов и т. д.? Я нахожу это довольно раздражающим, потому что я делаю арифметику указателей, как это в узком цикле, и я подозреваю,imul
убивает его производительность. В любом случае, это не должно быть необходимо.
Есть хороший способ предотвратить это вообще и вместо этого заменить это более дешевыми операциями?
Обновить:В моей исходной программе я попытался добавить фиктивную переменную, чтобы размер каждого элемента был кратным 4 вместо 3, чтобы компилятор мог использовать сдвиг битов вместо деления.
Результат? Несмотря на то, что структура данных была больше, время выполнения программы сократилось с 9,2 секунды до 7,4 секунды.
Так что да, это действительно очень медленно.