Member
Статус: Не в сети Регистрация: 31.01.2004 Откуда: moskow
Народ, а кто скажет почему вот такая функция (приведена ниже) работает на Р4 в три раза медленнее чем на АМД? Среда разработки Дельфи. Не такой же у дельфи ТУПОЙ компилятор?
_________________________________________________________________
function addSSE: Integer; stdcall;
begin
time1:=gettickcount;
for i:=1 to 160000 do
begin
asm
Member
Статус: Не в сети Регистрация: 28.02.2005 Откуда: Брянск
Ну для начала тут SSE использовать не надо (в этом коде ты складываешь только 1 компонент 4х компонентного регистра) - типа это все можно заменить на
mov eax,i
mov edx,i
add eax,edx
...(хотя быстрее наверное не будет)
Не ленись перепиши с исп. RDTSC (у тебя код по-моему очень быстро должен пролетать, 160к маловато (с gettickcount'ом) сделай чтоб несколко секунд вычислял), addss отнимает 4-5 тактов на Пне (на АМД не знаю, но наверное чуть меньше)(если потом переделаешь - напиши скока тактов(просто интересно)). И i можно в регистр загнать, т.е. без for'ов обойтись.
Кстати, разве не надо писать "movss xmm0,[i]"?
Member
Статус: Не в сети Регистрация: 31.01.2004 Откуда: moskow
<=Ну для начала тут SSE использовать не надо
=> Надо! я считаю количество операций в секунду
приблизительно получается 3000 млнсек на сел 2,8 и 9000 на AMD 3500+
Добавлено спустя 31 минуту, 5 секунд: "операций в секунду SSE"
<=Кстати, разве не надо писать "movss xmm0,[i]" -----------ненадо...
=====================================================
Еще желательно (для точности) выкинуть из цикла:
movss xmm0, i
movss xmm1, i
Интересно если написать:
asm
movss xmm0, i ->либо значение напр 5 переменная i нужна лишь для цикла.
movss xmm1, i ->либо значение напр 5 переменная i нужна лишь для цикла.
end;
сохранятся ли зхначения после закрытия асемблерной вставки и передадутся ли в следующую:
for i:=1 to 1000... do
asm
addss xmm0,xmm1
addss xmm0,xmm1
...
end;
================================================================
Member
Статус: Не в сети Регистрация: 28.02.2005 Откуда: Брянск
Locki У меня твой код выполняктся за ~53M тиков (вот и выходит ~5 тиков на инструкцию). Вопрос: как такой промежуток времени (~1/60 секунды на моем) можно замерить с gettickcount'ом?
2. Атлон никак не сможет выполнить 9 миллиардов операций за 1 секунду (для этого ему нужна частота в 3ГГц и инструкции типа xchg eax,eax (кот. он просто пропускает с пиковой скоростью в 3 опреации за тик)).
3. Про ССЕ - всмысле толку от него тут маловато. Но это неважно.
Кстати Атлон должен выполнять АДДСС за 4 тика, а МОВСС а 2. Скачай 22007.pdf с АМД - там написано какая инструкция скока жрет. И хватит тут for'ами пользоваться, раз взялся за АСМ чего уж отступать!!! Поменьше давай поводов компилятору неправильно тебя понять!
Member
Статус: Не в сети Регистрация: 28.02.2005 Откуда: Брянск
Locki Ещё лучше!!! Намекаешь на то, что FX55 (я понял в нем 2.6ГГц) выполняет в среднем около 6 инструкций за такт . Тебе не кажется что это уж очень много. Всётаки преходи на RDTSC - точнее будет.
Member
Статус: Не в сети Регистрация: 28.02.2005 Откуда: Брянск
Locki Прошу прощения - совсем засчитался. Но возникант другой вопрос - Какого так медленно? 3М/15М опреаций в сек - маловато простите будет. Ну напиши ты это с RDTSC (заодно результаты в циклах процессора), может это из-за gettickcount'a так мало выходит.
Member
Статус: Не в сети Регистрация: 31.01.2004 Откуда: moskow
Toad Блин я бы написал, но ГРЕБАННЫЙ ДЕЛЬФИ в ASM вставке не понимает МЕТКИ, а как без этого написать цикл на асме я не знаю, блин надо переходить с него на MASM, но для этого надо разобраться: как делать вMasm (винде) форму, кнопки, и т. д. в дельфях то ДРАГ&ДРОП И ПОЕХАЛИ!!!
Последний раз редактировалось Locki 12.07.2005 16:16, всего редактировалось 1 раз.
// цикл end inc ecx cmp ecx,1250000 jl @Loop rdtsc pop ecx sub eax,ecx pop ecx sbb edx,ecx mov takt1,edx mov takt2,eax // в регистрах edx:eax время выполнения цикла в тиках процессора end; takt:=takt2-takt1; label1.Caption:=inttostr(50000000 div takt)+'Опер/за Такт'; label2.Caption:=inttostr(takt div 50000000)+'Tакт/на Опер'; end;
А тут уже 19 тактов на операцию=> Вопрос тот же!
Добавлено спустя 4 минуты, 58 секунд: Asteroid Вот где собака порылась!!! а как это число загнать в одну переменную и какого типа??? int64???
Member
Статус: Не в сети Регистрация: 28.02.2005 Откуда: Брянск
Locki Естественно в инт64. Типа Такт=едх*(2^32)+еах. И зачем ты нижнюю половину инта64 из верхней вычитал? Вот у тя и цифры такие. А если цикл будет укладываться в 2^32-1 циклов, то можно вобще без инт64 обойтись.
// цикл end inc ecx cmp ecx,1 jl @Loop rdtsc pop ecx sub eax,ecx mov takt,eax // в регистре eax время выполнения цикла в тиках процессора end; add32:= takt / 8; //8 повторений в цикле (получается => затрачено тактов на операцию) end;
И тут если выше написанное правильно рождается такая странная вещь:
1 если я увеличиваю размер цикла и уменьшаю тело цикла, то количество тактов на операцию растет (ПРОИЗВЕДЕНИЕ НЕ МЕНЯЕТСЯ)
2 если я увеличиваю тело цикла, и уменьшаю размер цикла то количестео тактов на операцию падает (ПРОИЗВЕДЕНИЕ НЕ МЕНЯЕТСЯ)
ВОПРОС: не должно ли это количество для одного процессора быть НЕИЗМЕННЫМ!?!
Добавлено спустя 26 минут, 28 секунд: Короче че когда растет, а когда падает я может и перепутал (мозг уже отказывает), но факт , что значение НЕПОСТОЯННО!!!
Добавлено спустя 1 минуту, 30 секунд: И изменяется ЗАКОНОМЕРНО в 1 и 2 случаях.
Member
Статус: Не в сети Регистрация: 28.02.2005 Откуда: Брянск
Locki Извини обшибся, я имел в виду такты а не циклы. Нет не должно. Виндовс не даст твоей программе работать одной в течении большого промежутка времени (она же многозадачная) - поэтому результаты могут меняться (если только ты не укладывешься в промежуток кот. она тебе выделит на выполнение). Потом возможность исполнять несколько инструкций сразу - то же странная вешь (пробовал код из 8 загрузок + 8 операций + 8 сохранений результатов, самый быстрый вариант оказался 3з+3о+3с + 3з+3о+3с + 2з+2о+2с - вот так вот!). А для измерения кол-ва тактов использую вот это:
int TSC1H,TSC1L
Код:
rdtsc mov [TSC1H],edx mov [TSC1L],eax L0: ;Что-то надо сделать dec ecx cmp ecx,0 jnz L0 или loop L0 вместо 3х строк (иногда он быстрее +-4 такта) rdtsc sub eax,[TSC1L] sbb edx,[TSC1H]
А потом можно написать что-то вроде инт64 Такт=едх*(2^32)+еах. Но не уложиться в 1 секунду - это просто нереально. В среднем значения получаются какие надо.
rdtsc pop ecx sub eax,ecx mov takt,eax end; add32:= takt / 8;
Получается если:
1хADD eax,edx =84 такта на одну инструкцию
2хADD eax,edx =44 такта на одну инструкцию
4хADD eax,edx =22 такта на одну инструкцию
8хADD eax,edx =11 тактов на одну инструкцию
16хADD eax,edx =5 тактов на одну инструкцию
32хADD eax,edx =3,125 такта на одну инструкцию
64хADD eax,edx =от 8 до 1,8 такта на одну инструкцию
(постоянно разные значения в этих пределах)
При этом все это делается с приоритетом РИАЛ ТАЙМ!
Тут рождается мысль, что для Селерона 32хАdd оптимально, но например для того же пня4 это может быть не так, не говоря уже об AMD.
Тут рождается вопрос: как написать универсальную прогу которая бы показывала СКОЛЬКО ТАКТОВ ТРАТИТ ПРОЦЕССОР НА ТУ ИЛИ ИНУЮ ОПЕРАЦИЮ, при этом чтобы никто не кричал: "ОНА ОПТИМИЗИРОВАНА ПОД AMD или Intel!" ?
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения