народ, хочу почитать про кеш проца... точнее про работу с ним и оптимизацию под него... А то на новых камнях он уже больше мега, а нафиг оно надо не совсем понятно...Знаю только о том, что кое что там хранит сам проц... и еще о поточнее о разных уровнях кеша (L1-L3)
Block_prefect. Я заметил что его можно немного оптимизировать, если считывать сразу две линейки. Не смотря на известный пенальти в целом почему то получается быстрее: Код (Text): ;; sequential reads 2 cacheline test ebx, [esi + ecx + 00h] test ebx, [esi + ecx + 40h] ;; or line-spit reading test ebx, [esi + ecx + 3Eh] ;; load 2 cacheline Проверялось на iCel@2400 и AMD AthlonXP 2000+, не знаю как будет работать на более старых машинах.
alpet На PIII(celeron L1-16Кб,L2-128Кб, линия 32 байта) при "sequential reads 2 cacheline" заполнение всего L1 можно сделать за ~500 тактов, а при "or line-spit reading" уходит ~2500, как видишь пенальти огромное
bogrus вот-вот. На Атлоне ХР2000+ (VIA KT400, Kingston 512DDR400), при условии DC Miss, от 380 до 1000 тиков загрузка одной 64 байтной линейки, и порядка 740 - 1000 две сразу. По крайней мере такие результаты дает пайп-тест CodeAnalyst. У твоего Селерона весь L1 кэш 16Кб или только данных? У меня и DC и IC по 64кб на Атлоне и 8Кб / 12Kuops на Селероне. И еще - если при случае 2500 тиков страница не пересекается, то какое значение при пересечении границы страницы.
У меня и DC и IC по 16Кб, а причем страницы, зачем тебе измерять время загрузки страниц с винта или оперативы в L2? Такой результат у всех будет разный из-за особеностей контролеров, железа, памяти, менеджера памяти, я измерял время выполнения кода (перекачки данных из L2 в L1), вот попробуй такой тест для твоего атлона _2115644437__test.zip
На Атлоне только дома смогу. Сейчас провери на iCel@2400. cacheline1.exe: 000000000000000000319448 000000000000000000005744 000000000000000000002176 000000000000000000002152 000000000000000000002188 000000000000000000002172 000000000000000000002236 000000000000000000002132 000000000000000000002216 000000000000000000002204 cacheline2.exe: --------------------------- 00411490 / 12 bytes / 10 passes --------------------------- 000000000000000000320976 000000000000000000021824 000000000000000000020972 000000000000000000020944 000000000000000000020972 000000000000000000020976 000000000000000000020972 000000000000000000020972 000000000000000000020972 000000000000000000020972 Меня более всего интересует производительность цикла block prefetch. В аттаче мой варинан со сплиттингом, показывает правда результаты в мб/сек. На Celeron соответственно только чтение (Block Prefetch) ~2000 мб/сек, и чтение с доступом к кажому DWORDу ~1512 мб/сек. 832991992__mread.zip
Для своего селерона надеюсь ты поменял size на 1024*8 (L1 - 8 Кб), вот результат твоего теста Код (Text): CPU GenuineIntel @ 669 MHz Test results: read method read speed (64,0 Mb) scaner test 81 MiB/sec only prefetch 359 MiB/sec prefetch and read 94 MiB/sec
1. Нет, забыл. Вот с 8кбайтным тестом: cacheline1.exe: --------------------------- 00403490 / 15 bytes / 10 passes --------------------------- 000000000000000000038840 000000000000000000000280 000000000000000000000176 000000000000000000000156 000000000000000000000156 000000000000000000000156 000000000000000000000156 000000000000000000000160 000000000000000000000160 000000000000000000000160 cacheline2.exe: --------------------------- 00403490 / 12 bytes / 10 passes --------------------------- 000000000000000000034584 000000000000000000001912 000000000000000000001240 000000000000000000001240 000000000000000000001240 000000000000000000001240 000000000000000000001240 000000000000000000001352 000000000000000000001352 000000000000000000001352 В аттаче тот же тест, только с обычным чтением. На Селероне4 результаты практически не изменились - 1994 / 1505 мб/сек. Впрочем похоже здесь аппаратный префетч работает - если убрать цикл block prefetch скорость 3 алгоритма достигает 1560мб/сек. _1412657976__mread2.zip
А размер линии какой? Если 32 то тоже надо поменять: Код (Text): ;================обычн=============================необычн============ @@: mov eax,[esi+ebp] @@: mov eax,[esi+ebp+32-2] mov eax,[esi+ebp+32] add ebp,32*2 add ebp,32*2 jnz @b jnz @b ;===================================================================== Обычный получше Код (Text): CPU GenuineIntel @ 669 MHz Test results: read method read speed (64,0 Mb) scaner test 83 MiB/sec only prefetch 632 MiB/sec prefetch and read 155 MiB/sec
Около 145Mb/s (копирование), та у меня вообще частота шины 66MHz, два SDRAM PC100, нормальный средний комп Я сам то твой тест не посмотрел, там проставил свои параметры (CACHELINE = 32, CHESIZE = 1024*16), но результат странный, кажется там половину кода надо подганять? Код (Text): ;=обычн==========================сплит============================= CPU GenuineIntel @ 669 MHz CPU GenuineIntel @ 669 MHz Test results: Test results: read method read speed read method read speed (64,0 Mb) (64,0 Mb) scaner test 83 MiB/sec scaner test 81 MiB/sec only prefetch 632 MiB/sec only prefetch 358 MiB/sec prefetch and read 275 MiB/sec prefetch and read 156 MiB/sec ;===================================================================
Интересный результат - когда я на iCel@2400 запустил тест работающий с 32 байтными линейками, но обогнал тот что работает с 64-байтными по времени выполнения: <32byteline /8kb cache> Код (Text): CPU GenuineIntel @ 2405 MHz ... scaner test 539 MiB/sec only prefetch 2024 MiB/sec prefetch and read 1542 MiB/sec против <64byteline/8kb cache> Код (Text): scaner test 543 MiB/sec only prefetch 1976 MiB/sec prefetch and read 1514 MiB/sec Предположительно виновником затормаживания второго теста, является время от времени возникающий конфликт банков. Это показывает плохое влияние сильно развернутых циклов на производительность префетч блока. В качестве примера нейтрализации подобного конфликта, можно попытаться заставить процессор читать дважды, вот код куска цикла который выполняется с CACHELINE=64: Код (Text): repeat (400h / CACHELINE) test eax, [ecx + ebx + n] test eax, [ecx + ebx + n] ;; use Ls queue, n = n + CACHELINE end repeat В данном случае он выполняется с производительностью 2029mb/s, против 1885mb/sec с 32-байтными линейками. Кстати сама скорость - 2030мб/сек превысила выданный RMA прогноз read memory-bandwidth в 2020мб/сек. В аттаче сам тест слегка поправленный на макросы. 602336230__mread2.zip
CPU AuthenticAMD @ 2010 MHz Test results: read method read speed (64,0 Mb) scaner test 1065 MiB/sec only prefetch 5226 MiB/sec prefetch and read 3280 MiB/sec
MoKC0DeR Ты не поправлял в тесте CACHELINE=32, на 64? А то уж больно большой разрыв получается, для AMD64. С другой стороны - комманды могут максимум париться в используемом блоке чтения по 2-3 штуки, и для 2010Мгц частоты ядра получается вполне нормальный результат.
Вот сравнительные тесты на моем домашнем компе: CPU AuthenticAMD @ 1661 MHz Test results: read method read speed (64,0 Mb) scaner test 827 MiB/sec only prefetch 1693 MiB/sec prefetch and read 1462 MiB/sec cacheline1.exe: 000000000000000000024806 000000000000000000000175 000000000000000000000174 000000000000000000000174 000000000000000000000138 000000000000000000000138 000000000000000000000138 000000000000000000000138 000000000000000000000138 000000000000000000000138 cacheline2.exe: 000000000000000000023194 000000000000000000000468 000000000000000000000182 000000000000000000000161 000000000000000000000137 000000000000000000000137 000000000000000000000137 000000000000000000000137 000000000000000000000137 000000000000000000000137
Получается на атлоне нет таких пенальти, тогда есть смысл попробовать для него ускорить код, т.е. например на PIII цикл выполняется минимум 2 такта и за 2 такта можно сделать два чтения, по-этому цикл с одним чтением не рационально использует этот блок надо: замерить на атлоне 1000 проходов пустого цикла Код (Text): @@: dec ebp jnz @b Если результат будет ~2000, значит 2 такта на цикл, потом в цикл добавлять чтения пока не выйдем за рамки ~2000 Код (Text): @@: mov eax,[esi+ebp+32-2] mov eax,[esi+ebp+32*3-2] add ebp,32*4 jnz @b
bogrus Вообще с моим Атлоном все гораздо проще, могу сделать скриншот эмулятора конвеера показывающий все затраты на организацию цикла по тикам. Хотя если честно блок-преФетч циклы в нем выглядят очень неудобно - слишком длинные линейки эксплуатации каждого конвейера получаются из-за вывода пенальти DC-Miss (в ряде случаев до 1000 тиков). Накрайняк могу представить DPI (delta per instruction) для предложенного кода, это в общем случае соответствует количеству тиков.
народ, насчет теста: есть некий алгоритм, я хочу его прогнать например 0xFFFF раз =) и узнать время его выполнения, это реально? как вообще толком отследить, сколько выполняется та или иная часть кода