здравствуйте как обращаться к элементам-dword двумерного массива (двойные слова по 6 шт в строке)? масштабирование разрешает коэфицент не больше 8, а в моём случае он должен быть 24 приходится умножать индекс строки в eax на 24, и обращаться str[eax+регистр_с_индексом_столбца_умноженый_на_4] - есть ли какие другие более быстрые/короткие пути?
http://www.wasm.ru/forum/viewtopic.php?pid=169885#p169885 кстати запись в форме [base+scale*index] "красивее" но не быстрее чем "самостоятельное вычисление" адреса.
Y_Mur Хочешь сказать, что Код (Text): imul eax,edx,24 mov eax,[base+eax] Будет быстрее чем Код (Text): lea eax,[ebx*2+ebx] mov eax,[base+eax*8] И этого Код (Text): mov eax,ebx shl eax,3 mov eax,[base+eax*2+eax]
Y_Mur ?? Вычисление адресов операндов памяти производится на отдельных спецблоках и соотв-но может производиться параллельно с операциями АЛУ, а "самостоятельное вычисление" ес-но занимает АЛУ и может мешать другим операциям. А вот mov eax,[edx] и mov eax,[edx+ecx*8+offs] действительно выполняются за одно время
leo перепроверил - действительно с поправкой на некоторые любопытные аномалии так и есть - "выполняются за одно время" (примерно) - это меня глюк в одном из прошлых тестов ввёл в заблуждение. murder я имел в виду что при "самостоятельном вычислении" нередко можно вообще отказаться от сдвига\умножения немного подкорректировав понятие "индекс" )
решил индексировать строки не по 1, а по 3 - соответственно str[esi*8+edi] даст тот же адрес что и str[eax*24+edi] а на выводе буду просто делить на 3 потому что вывода в моём случае будет раз в 100 000 меньше, чем циклов с индексацией то-есть 1 деление на 3 + 300 000 inc против 100 000 умножений на 24 + 100 000 inc
leo Не везде. Что касается P4 Intel LEA разбивается на микро инструкции. Это же подтверждает Агнер фог. Латентность больше и мопсов больше. В зависимости от вида инструкции. На других процесорах по другому. У AMD64 за такт для любого случая. ThunderCode Что ксается цикла то тут можно в замен умножение использовать счетчик цикла который будет увеличиваться/уменьшаться на длину строки. Тем самым мы избавимся от умножения как такового.
ThunderCode К примеру массив 6x12 Код (Text): mov edx,5 mov eax,x shl eax,2 mov ebx,0 mov ecx,12 @pp: lea ebx,[ebx*2+ebx] add dword [base+ebx*8+eax],edx add ebx,1 loop @pp Тут экономим умножения. Код (Text): mov edx,5 mov eax,x shl eax,2 lea eax,[base+eax+11*6*4] ;11*4*6- константа @pp: add dword [eax],edx sub eax,6*4, ; Цикл в loop входило dec cx jae @pp ; Если больше или равно
Pavia Код (Text): @pp: add dword [eax],edx sub eax,6*4, ; Цикл в loop входило dec cx jae @pp Меня очень удивило, что ТЫ написал ТАКОЕ. Ведь при движении в обратном направлении будет происходить чтение не из кеша, а из памяти. Может я неправ? Разъясни.
murder Круто сказано )) Во первых даже если hardware prefetch однонаправленный, то это сказывается только на первом обращении к очередной линейке КЭШ, последующие обращения кешированы независимо от того с какой стороны считан первый byte/dword Но в современных камушках:
Pavia Я имел в виду вычисление адресов операций, реально обращающихся к памяти (mov, add и т.д.) - на всех процессорах они выполняются на спецблоках (в атлонах - AGU, в пеньках - load data или store address). LEA же только вычисляет адрес и к памяти не обращается. В атлонах LEA выполняется на AGU и соотв-но может влиять на поток команд load\store, а в пеньках - на АЛУ и соотв-но должна учитываться в потоке АЛУ-команд. Ну а про первые P4 и говорить нечего, т.к. это наспех состряпанные "пробные камни", у которых ни спец.целочисленного умножителя нет, ни сдвигателя (все на ММХ делается), ни соотв-но и спецподдержки LEA. К тому же и T-кэш куций - в одном мопе может храниться только 16 битное непосредственое значение и вторые половинки 32-битных рассовываются по соседним или дополнительным мопам ?!