2016-12-23 4 views
-2

Как повысить производительность следующего фрагмента кода в сборке? Пожалуйста, предложите, какие у меня есть способы сделать это?Как повысить производительность этого фрагмента кода путем сборки?

void changeDirection(char key) { 
    /* 
     W 
    A + D 
     S 

    */ 
    switch (key) { 
    case 'w': 
     if (direction != 2) direction = 0; 
     break; 
    case 'd': 
     if (direction != 3) direction = 1; 
     break; 
    case 's': 
     if (direction != 4) direction = 2; 
     break; 
    case 'a': 
     if (direction != 5) direction = 3; 
     break; 
    } 
}/******increase performance*****/ 

Благодаря

+4

я могу в значительной степени гарантировать любой современный компилятор повернет, что в более быстрой сборки, чем подавляющее большинство разработчиков могли производить вручную :-) – paxdiablo

+3

Неужели это только один раз за игру? – harold

+3

невозможно сказать без окружающего контекста. Получение оптимального asm для простого отображения цифры ASCII в число не полезно, если это связано с другим кодом, который делает что-то условное на основе числа. Надеемся, что 'direction' является' static' или что-то, поэтому компилятор может более легко оптимизировать его в регистр при встраивании этой функции. –

ответ

3

На самом деле в конце 2-5 диапазон против 0-3 диапазона оказался просто злоупотребляют (хотя я боюсь, что это не то, что вы хотите).

Плюс обычные игры допускают ключевое переопределение, которое полностью нарушит это. Так что это больше похоже на «шутку», чем на серьезный ответ. Но ваш вопрос тоже стоит на грани «шутки», я имею в виду: у вас есть более серьезные проблемы, если вы действительно считаете, что вещь в вашем посте является проблемой.

// I expect "direction" to be int, otherwise change wantDir vars 

void changeDirection2(char key) { 
    //          a  s d   w 
    constexpr static int wantDir[] = { ~0, 3, ~0, 2, 1, ~0, ~0, 0 }; 
    int wantedDir = wantDir[key&7]; 
    if (wantedDir+2 == direction) return; 
    direction = wantedDir; 
} 

Плюс это будет реагировать на многие другие (все из них) ключи, чем a, w, s, d. Это зависит от вызывающего звонка только с правильными.


версия 2, без LUT (еще HARDCODED к «AWSD» и коверкая любой другой ключ в некоторое количество):

void changeDirection3(char key) { 
    int wantedDir = (~key>>1)&3; 
    if (wantedDir+2 == direction) return; 
    direction = wantedDir; 
} 
+0

Я бы выделил, кроме того, предотвратит автоматическое удаление вопроса за 30 дней. Если это часто называется * очень часто, это LUT на самом деле неплохое. Хм, что, если вы избегаете кэша, упущенного, реализуя LUT в качестве сдвига правого сдвига в переменную с помощью клавиши «4», а затем принимая низкий кусок? Таким образом, LUT представляет собой просто 32-битную константу, которую вы переводите в регистр. –

+0

'shl edi, 2' /' mov eax, 0x0FF12F3F'/'shrx eax, eax, edi' /' и eax, 0x0F'. Может быть, cmov обрабатывает ветку, поэтому магазин «direction» всегда происходит. Или нет, поскольку ветвление, чтобы избежать хранилища (в этом случае только), избегает цепочку зависимостей, зависящую от цикла, на «направлении», если она находится в узком цикле. (Не знаю, почему это было бы для этого случая, но если вы использовали эту идею для чего-то, где оптимизация важна ...) –

+0

@PeterCordes на самом деле я не понял «правую смену» после быстрого чтения, и мне пришлось что-то сделать за несколько секунд, прежде чем вернуться к ЖК-дисплею, поэтому мой разум тем временем «понял». 'wantedDir = ((ключ >> 1)^3) & 3;' ... затем я снова прочитал ваше предложение, hm. :) – Ped7g

Смежные вопросы