Определение размера и ассоциативности D-TLB

Тема в разделе "WASM.ASSEMBLER", создана пользователем ilvip, 19 окт 2006.

  1. ilvip

    ilvip New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2006
    Сообщения:
    6
    Необходимо написать небольшой тест для непосредственного определения размера и ассоциативности TLB (точнее, L1 D-TLB).
    Если кто знает, как это сделать - помогите, плз!
    Кстати, вроде на некоторых проц. есть L2 D-TLB, для него можно какие-либо параметры определить?
     
  2. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    URL http://www.agner.org/optimize/asmlib.zip
    там пример теста с исходниками, подробно не разбирал, но может подойдёт
     
  3. ilvip

    ilvip New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2006
    Сообщения:
    6
    Y_Mur, спасибо, как получить эти цифры при помощи этой программы разобрался. Остался вопрос: как продемонтрировать, что TLB действительно такого размера (в программе, точнее, в процедуре INTERPRET_TLB, насколько я понял, просто идет получение информации, грубо говоря, "зашитой в процессоре").
    Т.е. надо построить какой-либо тест, который, например, на некотором наборе размера меньшего размера TLB работал бы быстрее, а с увеличением набора скорость разко падала (например, как это сделано в тесте RightMark Memory Analyzer). Или показать, что некоторый код без оптимизации под TLB работает плохо, а с оптимизацией - хорошо.
     
  4. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    ilvip
    Просто замеряешь по rdtsc время чтения N двордов, каждый со смещением на 4К+64 от предыдущего (64 - размер линейки кэша). При N = числу записей TLB будет скачок (для наглядности лучше пересчитать время в скорость R=t*k/N, k - масштабный коэфф.)
     
  5. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    Боюсь, что с подобным тестом ничего не выйдет. Программно нельзя отключить/включить TLB. Единственное, что можно делать - это постоянно сбрасывать кэш TLB перезаписью Cr3 или инструкцией invlpg. Но для этого придется загружать драйвер, который в цикле будет постоянно сбрасывать кэш. Но это явно не совсем честное решение.
    ЗЫ: Любая информация о возможностях процессора, в т.ч. и кэшах, может быть получена с помощью cpuid. См. Intel Manual
     
  6. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    leo
    Интересная идея!
     
  7. ilvip

    ilvip New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2006
    Сообщения:
    6
    leo, самое обидное, что я в общих чертах так и делал. При этом - из-за кривизны рук, похоже - результата никакого (т.е. число тактов на одно чтение стабильно держится в районе 3 при включенном кэшировании и в районе ~60 без кэширования, вне зависимости от числа чтений).

    Если у кого есть возможность - посмотрите программу, может найдете стратегические просчеты...

    Идея такая: создали массив указателей на void (как раз 32 бита размер каждого), нулевой элемент ссылается на (4К+64)ый, ... и так далее, (i*(4K+64))ый - на нулевой, где i изменяем от 2 до 512 в цикле. В этом же цикле вызываем такую функцию (count передаем 1000*i, в src - указатель на нулевой элемент):
    Код (Text):
    1. void __declspec(naked) __cdecl ReadTLB(void* src, __int32 count)
    2. {
    3.     __asm
    4.     {
    5.         mov         eax, [esp+4]    // поместить src в eax
    6.         mov         ecx, [esp+8]    // поместить count в ecx
    7.         ALIGN       16             
    8. $loop:
    9.         mov         eax, [eax]      // Записать в eax то, что лежит по адресу в eax
    10.         mov         eax, [eax]      // Ещё раз
    11.         sub         ecx, 2
    12.         jnz         $loop
    13.         ret
    14.     }
    15. }
    Время при помощи rdtsc засекаем для всего выполнения процедуры.

    Так вот, все эти манипуляции к результату не приводят, увы. Интересно, где накосячил?
     
  8. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    ilvip
    Перемудрил с указателями, вот и накосячил ;)
    m1[k*stride] = &m1[k*(stride+1)] пишет в m1[0] указатель на самого себя и в результате ReadTlb всегда читает один и тот же dword m1[0]. Видимо нужно &m1[(k+1)*stride]. И кстати не понятно почему stride=4K+65, а не 64 - какой в этом смысл ?

    Если речь идет только о тесте TLB (а не вообще скорости чтения), то PAGE_NOCACHE и сброс TLB (да еще в ринг 0 ради записи в cr3) - тут совершенно ни к чему, т.к. это лишь добавляет лишние задержки, которые скрывают и зашумляют точку излома
    К тому же сама методика с накручиванием по 1000 проходов, да еще для всех (i=512; i>2; i-=2) и без REALTIME_PRIORYTY чревата случайными выбросами за счет виндовых "происков" с переключением потоков. В данном случае ИМХО "лучше меньше, да лучше" ;)
     
  9. ilvip

    ilvip New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2006
    Сообщения:
    6
    leo, спасибо. 65 - это описка, как и нулевой шаг. Другое дело, что на моем раритетном PentiumII-300 этот код ни после каких манипуляций так и не заработал.
    В итоге догадался, переписал под Линух и запустил на P3 - нормально отработало. Так что проблема исчерпана, ещё раз спасибо за помощь.