Y_Mur Не спеши с выводами Clerk на P4 тестил, а ты видимо на атлоне. У меня на атлоне под SP2 практически те же цифири получаются, что и у тебя, так что дело не в SP и ОС, а в проциках
leo почти Turion 64 X2 TL-58 но не может же "чуть чуть другой" камешек на одном и том же коде давать ускорение почти на порядок 24000 vs 2800, при том что другая "версия" функци работает практически одинаково 34335 vs 28796 Наверное тогда дело в разных ядрах, у меня соответственно стоит AmdK8.sys, скачанное с амд сайта.
leo О_о как я сразу не подумол. Этож не время замеряет, а тики системные, которые от производительности проца зависят. Нужно связать со временем както, хотябы тики ядра считать, или пересчитать дельту тск за время. Прикинул вобщем, можно заюзоть профилирование(APIC, NtSetIntervalProfile etc), но это для быстрых вызовов не знаю как заработает, либо можно открыть прямой ввод-вывод и заюзоть PIT, на небольших интервалах(секунды) погрешность не заметна, а период 0.8мкс, должно хватить.
Y_Mur [offtop] Если в клипборде уже имеется (непустой) текст - по кнопке не копируется. А вообще-то кнопка на мессаджбоксе и соотв. код для копирования в клипборд - перебор Для мессаджбокса достаточно просто Ctrl-C (либо Ctrl-Ins) [/offtop]
Dian тут где-то обсуждалось что из-за экономии питания rdtsc тик может измениться в 2 раза, но 2 это не 10 и вообще имхо именно такой расклад как в таблице маловероятен из-за глюков измерения - тут что-то системное kero спасибо - не знал и Clerk судя по #4 тоже
Да никакое это не "ускорение", "хрень rdtsc" и т.п., а просто дебильный HT в P4 всю идилию портит Cобрался наконец с отключенным HT проверить - полет вполне стабильный и нормальный Код (Text): ----------------------------------------------- P4 HT-off Athlon 64 x2 VirtualAlloc (system address, commit 10Mb) 0:6932 0:3283 VirtualAlloc (system address, reserve 10Mb) 0:6512 0:3570 VirtualAlloc (commit 1Mb in reserve) 0:15228 0:20473 VirtualAlloc (commit 9Mb in reserve) 0:48056 0:132832 Тут уж разницу можно и на различие процев списать А с HT ес-но цифры ужасно скачут в зависимости от загрузки компа
leo ясненько спасибо В общем основной вывод - предварительно резервировать память без особой необходимости не стоит - будут странные тормоза
Как-то уж подозрительно одинаково шустро работают reserve и reserve+commit. Может когда сразу вызывается commit, то таблицы страниц не создаются ? А когда commit после резерва, то создаются и время соотв-но возрастает. Если это так, то в первом случае первое обращение к странице должно занимать намного больше времени, чем во втором.
leo проверил - время первого доступа одинаково тормозное ) И оно намного больше чем само выделение памяти (т.е. на его фоне различие в тормозах функции мелочь , но с другой стороны оно может "размазываться" по программе, хотя практической пользы от этого размазывания никакой - время-то всё равно рано или поздно потратится Было бы здорово запустить цикл команд prefetch(w\t0\t2), чтобы они "фоново" подгрузили такие страницы, но увы эти команды не вызывают ошибку доступа к несуществующей странице, а если бы и вызывали, пользы бы не принесли - всё равно обработчик этих ошибок съел бы те же самые такты, ничего не позволив сделать параллельно. В общем я опять поймал блоху, которую даже и подковать то толком не получится ) зы: поправил багу с клипбордом
Для полноты картины решил сравнить время обнуления страниц во время первого доступа с различными вариантами самостоятельного обнуления тех же самых страниц. Получилось, что система обнуляет страницы в ~2 раза быстрее чем суперпупер оптимизированные подходы (небольшое преимущество AMD префётча перед Intel-овским по видимому связано с тем, что тестируемый процессор AMD . Возникло подозрение, что система имеет "заначку" заранее заготовленных обнулённых страниц, тогда выделение большого буфера, чтение выделенных страниц (чтобы они обнулились, но не "запачкались") и освобождение должны "пополнить эту заначку" и ускорить последующее обнуление - но эта версия не подтвердилась - время доступа при таком повторном выделении не изменяется. Значит здесь действует какой-то хитрый механизм аппаратного обнуления с удвоенной скоростью (кто знает где про него почитать подскажите пожалуйста . Чтобы разобраться с "хренью rdtsc", она же SpeedStep добавил сравнение тактов с QueryPerformanceCounter (тест 12 первый столбец) и временем GetTickCount в мс (тест 10, в котором пришлось в 10 раз увеличить объёмы памяти, чтобы хоть, что-то разглядеть). Тесты показали, что msdn заявляя: нахально врёт и на самом деле эта частота у меня (XP sp3) гуляет в соответствии со SpeedStep и поймать удачный/адекватный тест удаётся лишь изредка, а так постоянно как раз двухкратные "недоразумения". А rdtsc собственно даёт более реальную картину (во всяком случае в тактах), правда процессор на таких операциях как VirtualAlloc и обнуление памяти всё время "зевает" (в смысле норовит расслабиться и подремать на половинной частоте) и приходится его "взбадривать" - @@: loop @B в варианте с GetTickCount, но это помогает только частично - соотношение времени в тактах и в мс всё равно непропорциональное Код (Text): AMD Turion(tm) 64 X2 Mobile Technology TL-58 family.model.stepping = 15.8.2 === GetTickCount === ------------------------------------------------------------------------------------- VirtualAlloc (system address, commit 100Mb) 0 мс | 0:15303 VirtualAlloc (system address, reserve 100Mb) 0 мс | 0:9270 VirtualAlloc (commit 10Mb in reserve) 0 мс | 0:153839 VirtualAlloc (commit 90Mb in reserve) 0 мс | 0:1338229 доступ - commit 31 мс | 0:69363989 доступ - commit + reserve 32 мс | 0:66003594 доступ - повторный commit 100Мб 32 мс | 0:66391804 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - обнуление rep stosd 94 мс | 0:168113953 обнуление 32 (eax) + prefetchw (AMD 3DNow) 78 мс | 0:151379737 обнуление 64 (mmx) + prefetchw (AMD 3DNow) 78 мс | 0:149112769 обнуление 128 (xmm) + prefetchw (AMD) 78 мс | 0:148600571 обнуление 32 (eax) + prefetcht0 (Intel SSE) 78 мс | 0:157473671 обнуление 64 (mmx) + prefetcht0 (Intel SSE) 93 мс | 0:150980947 обнуление 128 (xmm) + prefetcht0 (Intel SSE) 78 мс | 0:149662790 ------------------------------------------------------------------------------------- === QueryPerformanceFrequency === ------------------------------------------------------------------------------------- VirtualAlloc (system address, commit 10Mb) 0:13 | 0:3458 VirtualAlloc (system address, reserve 10Mb) 0:12 | 0:3064 VirtualAlloc (commit 1Mb in reserve) 0:343 | 0:177947 VirtualAlloc (commit 9Mb in reserve) 0:186 | 0:95090 доступ - commit 0:13565 | 0:7175664 доступ - commit + reserve 0:11940 | 0:6316959 доступ - повторный commit 10Мб 0:13266 | 0:7018163 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - обнуление rep stosd 0:31012 | 0:16412244 обнуление 32 (eax) + prefetchw (AMD 3DNow) 0:27944 | 0:14785096 обнуление 64 (mmx) + prefetchw (AMD 3DNow) 0:29231 | 0:15469902 обнуление 128 (xmm) + prefetchw (AMD) 0:28599 | 0:15131403 обнуление 32 (eax) + prefetcht0 (Intel SSE) 0:28902 | 0:15294208 обнуление 64 (mmx) + prefetcht0 (Intel SSE) 0:29399 | 0:15557089 обнуление 128 (xmm) + prefetcht0 (Intel SSE) 0:27351 | 0:14470068 ------------------------------------------------------------------------------------- ЗЫ: MASM32 от Hutchessona не поддерживает xmm, нужен масм посвежее
Что-то у тебя скорость записи хиловатая получается 100Мб/80мс = 1.25Гб/с Вместо того, чтобы с prefetchw связываться лучше бы movntq заюзал
Y_Mur И что значит "посвежее" со сцылкой на 8-й, если уже 10-й все вовсю юзают? http://www.masm32.com/download/beta10k.zip
виста P4 прескот запуск 1 Код (Text): VirtualAlloc (system address, commit 10Mb) 0:11432 VirtualAlloc (system address, reserve 10Mb) 0:9288 VirtualAlloc (commit 1Mb in reserve) 0:22472 VirtualAlloc (commit 9Mb in reserve) 0:69264 äîñòóï - òîëüêî commit 0:21085984 äîñòóï - reserve + commit 0:18528944 запуск 2 Код (Text): VirtualAlloc (system address, commit 10Mb) 0:10560 VirtualAlloc (system address, reserve 10Mb) 0:8200 VirtualAlloc (commit 1Mb in reserve) 0:38176 VirtualAlloc (commit 9Mb in reserve) 0:75048 äîñòóï - òîëüêî commit 0:19935112 äîñòóï - reserve + commit 0:18045240 запуск 3 Код (Text): VirtualAlloc (system address, commit 10Mb) 0:14208 VirtualAlloc (system address, reserve 10Mb) 0:9856 VirtualAlloc (commit 1Mb in reserve) 0:31376 VirtualAlloc (commit 9Mb in reserve) 0:69152 äîñòóï - òîëüêî commit 0:20824240 äîñòóï - reserve + commit 0:18519680 ЗЫ 52 процесса запущено
_Aspire там уже и не бетта 10 давно есть только, это версия пакета от Hutchessona, а компилятор там посмотри какой и заодно попробуй им SSE2 скомпилить leo огромное спасибо - вот он секрет системного обнуления с удвоеннной скоростью ) А интересно почему если к movntq добавить prefetchw то скорость опять падает в два раза? я думал префётч полностью прозрачен
Y_Mur Ага, типа "слышал звон" Маны нужно внимательнее читать и улавливать суть, а не отрывочные "упрощенные правила" и кодинг-рулы Прочитай внимательно главу Prefetch instructions в мануале по оптимизации AMD и поймешь, что с movnt нельзя использовать никакие другие операции чтения\записи\префетча по тем же адресам, т.к. movnt копит данные в спец.WC-буферах и сбрасывает их прямо в память, минуя кэш. Вообще говоря, ОЗУ, кэш и WC-буферы это разные альтернативные\эксклюзивные хранилища данных, т.е. для обеспечения целостности в каждый момент времени актуальные данные могут находиться только в одном из этих хранилищ. Поэтому при любом обычном (кэшируемом) обращении к памяти, включая все префетчи, при кэш-промахе первым делом проверяется нет ли соотв.адресов в WC-буферах - если нет, то данные грузятся из ОЗУ в кэш, если же есть, то сначала производится сброс данных из WC-буферов в память и только затем они грузятся из ОЗУ в кэш. И наоборот, при movnt сначала проверяется нет ли соотв.линейки в кэше - если есть и модифицирована, то сначала эта линейка сбрасывается из кэша в ОЗУ и только после этого данные пишутся в WC-буфер. Поэтому юзать вместе с movnt какие-либо префетчи по тем же адресам - это глупость, а prefetchW - глупость в квадрате, т.к. prefetchw не только бесполезно грузит данные из ОЗУ в кэш (хотя для movnt они нафиг в кэше не нужны), но еще и (ради жалкой экономии пары тактов) сразу помечает соотв.линейку кэша как модифицированную, поэтому перед movnt процессор вынужден тупо сбрасывать эту линейку опять в ОЗУ, хотя данные в ней фактически не изменялись ?!! PS: Вообще польза от prefetchW довольна сомнительная, поэтому интел ее и не поддерживает. Вот если бы prefetchW не грузила данные из ОЗУ, а просто бы выделяла строку в кэше в расчете на то, что она будет полностью переписана - тогда другое дело. Но из-за всевозможных исключений\прерываний\спин-блокировок и т.п. строка может оказаться модифицированной не полностью, а частично и придется усложнять логику контроля и сброса в ОЗУ частично модифицированных строк. Поскольку делать это для всего кэша слишком накладно, то для этого и юзают ограниченное число WC-буферов с побайтным контролем модификации. Если 64-байтный буфер записан полностью, то он целиком сбрасывается в ОЗУ за один запрос (т.е.быстро), если же частично - то сброс осуществляется частями с соотв.масками (т.е.медленно)