"Оптимизация для PENTIUM процессора" - читать интересную книгу автора JNZ L1 ; v (спаривание)
NEG EAX NEG EBX MOV [EDI+4*ECX-8], EAX MOV [EDI+4*ECX-4], EBX L3: Хитрость в том, что бы найти спаривающиеся инструкции, таким образом, что бы не использовать счетчик цикла как индекс и реорганизовать цикл так, что бы счетчик цикла увеличивался в предыдущем такте. Таким образом мы достигли 5 тактов для двух операций, приблизившись к лучшему из возможных решению. Если кеширование данных является критическим, то можно увеличить скорость объединив массивы A и B в одну структуру что бы каждое B[i] находилось после соответствующего A[i]. Если структура массива выравнена, то по крайней мере на 8, то B[i] будет всегда находиться в той же строке, что и A[i] и у вас никогда не будет промахов кеша при записи B[i]. Конечно это приведет к усложнению других частей программы, так что вы должны взвесить все преимущества и недостатки. Развертывание более чем в 2 раза -------------------------------- Вы можете подумать, что исполнение более двух операций за одну итерацию приведет к еще большей производительности цикла. Правда потери цикла не всегда могут сводиться к одному такту за итерацию, так что развертывая цикл в 4 раза, стоит бороться. Только если потери не сводятся к одному такту и N велико стоит думать о развертывании в 4 раза. Недостатки через мерного развертывания цикла: 1. Вам необходимо вычислить остаток от деления N на R, где R - коофициент развертки и выполнять этот остаток до или после основного цикла, что бы сделать кол-во операций делимым на R. Это потребует дополнительного кода с плохо предсказуемым ветвлением. И, разумеется, увеличиться тело цикла. 2. Код, обычно, требует больше времени при первом исполнении, чем при повторах и большое тело цикла будет выполняться дольше первый раз, что актуально, если N невелико. 3. Через мерный размер кода уменьшает эффективность кеша кода. Обработка команд с 8 или 16 битными оперндами - частями 32 битных регистров --------------------------------------------------------------------------- Если вам надо манипулировать с массивами 8 или 16 битных значений, то у вас может возникнуть проблема с развертыванием цикла из-за того, что вы не сможете добиться спаривания операций доступа к памяти. К примеру MOV AL,[ESI] / MOV BL,[ESI+1] не спариться, если оба операнда лежат в пределах одного двойного слова в памяти. Но существует более простой способ, призванный что бы оперировать со всеми четыремя байтами в одном 32 битном регистре. Следующий пример увеличивает на 2 каждый элемент массива байт. |
|
|