Как избежать умножения в арифметике указателей?

Если я напишу

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 секунды.

Так что да, это действительно очень медленно.

Ответы на вопрос(1)

Ваш ответ на вопрос