Скорость+оптимизация

Тема в разделе "WASM.A&O", создана пользователем Sonic, 19 май 2005.

  1. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    кстати, я решил (для надежности) брать в качестве оверхеда не последнее значение, а прогонять цикл 12 раз, затем отбирать только то число, которое гарантировано встречается не менее 7 раз

    тоже самое делаю и при замере нужного кода (это я пробовал сделать привязку к железу через rdtsc), т.е. принцип такой:

    - есть процедура берущая оверхед (proc %overhead)
    - есть множество ф-ций, скорость выполнения каждой из которых, зависит от какой-то определенной характеристики железа
    - есть процедура замеряющая скорость выполнения тестируемой функции, переданой в качестве параметра (proc %rdtsc,%proc)

    это все ясно и хорошо, но! результат есс-но нестабилен, даже на простых ф-циях (это у меня на pentium d одна и таже ф-ция может иметь два стабильных результата, но чередующиеся через раз, на старом pIII такой проблемы нет), а тем более на ф-циях, замеряющих к примеру, скорость обращения к первому сектору hdd, там результат получается с разбросом, допустим:

    000000000000000635342315
    000000000000000635385424
    000000000000000635421245
    000000000000000635389641
    ...

    Из этих чисел, делая между ними AND и отбирая только неизменяющиеся биты получаем стабильное число, затем (чтобы исключить возможность брутфорса) убираем все биты, которые гарантировано встречаются в результатах ф-ции на всех возможных машинах, таким образом у нас остается несколько там десятков бит, стабильно прыгающих на разном железе

    - есть процедура, собирающая все такие биты ф-ций в одно 128 битное число (оно будет ключем шифровки\дешифровки защищенного кода)

    т.е. на клиентской машине получаем ключ и под него генерим копию программы, запущенная у клиента программа - делает тоже самое, но с небольшим дополнением:

    - иногда (из-за вспышек на солнце)) какой-то бит может все таки прыгнуть
    - для этого, процедура расшифровки повторяется 5-10 раз, пока CRC не совпадет с ключевым
    - если за это, n-ное кол-во так и не удалось правильно расшифровать - значит с железом что-то не то
     
  2. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    leo
    Ура заработало - огромное спасибо!
    есть выигрыш в 30 тиков на PII !!!
     
  3. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    Позвольте уж и мне на суд столь уважаемых Дзенствующих выставить маскос писаный мной давненько под masm. Замечания и конструктивная критика приветствуется.
     
  4. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    bogrus
    Насчет оверхеда ты в общем прав, хотя ИМХО на "простых" камнях разброса практически нет, а на P4 с HT=on получить повторяющиеся значения вообще проблематично - только отключать HT. Поэтому отбор гарантированных повторов видимо актуален для двухядерников, хотя и тут ради эксперимента лучше отключать второй процессор.
    И потом если речь идет о тестере (а не о генераторе ключа), то я предпочитаю видеть глазками разброс значений и для надежности повторять тест несколько раз, а не выводить какое-то одно значение - будь оно повторяющееся или вообще какое-то непонятное среднее ;)

    Ну и как вердикт ? Вспышки на Солнце не достают ? ;)
    PS: Для "простых функций" разброс на Pentiun D это ИМХО цветочки по сравнению с кашей на HT - тут на одном проце рулят два конкурирующих потока, поэтому и разброс значений может быть практически любым, и измерять более или менее надежно можно видимо только достаточно большие "внешние" задержки. Или я не прав ?

    Y_Mur, asmfan
    1) Повторю - rdtsc is not a serializing instruction, subsequent instructions may begin execution before the read operation is performed, т.е. тестируемый код может выполняться параллельно с rdtsc и сохранением edx:eax. Поэтому непосредственно перед тестируемым кодом нужно вставлять cpuid, т.е. всего их должно быть 3 шт. - перед каждым rdtsc и перед тестируемым кодом.
    2) Задержка самой cpuid зависит от наличия записи в память в предыдущем куске кода, т.к. cpuid форсирует сброс содержимого буферов записи в кэш. Поэтому если тестируемый код ничего в память не пишет, то на P6 результаты получаются "тик в тик" (или в худшем случае на 1 тик меньше за счет спараллеливания с xor eax,eax), а на P4\P4E результаты получаются с дискретом в 4\8 тиков соотв-но. Если же тестируемый код пишет в память, то итоговая задержка получается больше на несколько десятков тактов - тут остается либо 1) не обращать внимания на абсолютную задержку и проводить только относительные сравнения разных вариантов с одинаковым числом записей в память, либо 2) пытаться заменить cpuid перед последним rdtsc на нечто другое - в частности на пеньках неплохие результаты дает инструкция cld - результата "тик в тик" не получим, но по кр.мере он будет гораздо ближе к истине, чем при cpuid
     
  5. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    leo
    Учел замечания и соединил два теста в один.

    Первое значение без цикла второе в цикле
    PII 266 МГц Pentium M 1,6 ГГц Celeron 2,8 ГГц
    std 239, 239 244, 237 380, 267
    new 209, 192 206, 161 316, 230

    Интересно, что значение в цикле намного меньше, чем просто от спаривания с кодом цикла и от задержки записи в память, т.е. получается оно как бы характеризует способность кода спариваться с самим собой?
    И где здесь более корректный "дифференциальный" результат в цикле или без?

    Еще попробовал в std заменить FSTP [qZ] на FSTP ST(0) :
    PII: 239, 239 <- пишет в память
    238, 237 <- не пишет в память
    т.е. практически без разницы
    Celeron: 380, 267 <- пишет в память
    348, 267 <- не пишет в память
    т.е. получается цикл тоже позволяет абстрагироваться от записи в память, если конечно считать "самоспаривание" нормальным явлением.
     
  6. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Y_Mur
    Это нормальное явление для цикла и ненормальное для "нецикла" :lol:
    Поэтому в общем случае в цикле можно корректно тестировать только сами циклы :)
    А если хочешь "выцепить" малые задержки небольших кусков кода или вообще латентности отдельных инструкций, то универсальных методов тут нет и нужны специальные квазинаучные эксперименты а ля доктор Фог (у которого кстати, тоже не все безупречно - например, он продолжает утверждать, что в P4\P4E у adc,sbb througput = 8\10, хотя и мануалы Intel и элементарные проверки дают цифры ~2-3). Поэтому осчастливить начинающих оптимизаторов универсальным тестером на все случаи жизни не удастся ;)) И поэтому нагружать тестер измерениями в цикле ИМХО ни к чему - кому надо, тот сам три строчки добавит для организации цикла, а чтобы проще было "делить в уме" для получения задержки на итерацию достаточно просто брать число итераций = 100, 1000 и т.д. - тут кстати и штраф за непредсказанный выход из цикла будет виден и задержка на выгрузку буферов в кэш
     
  7. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Не я собственно делаю не универсальный, а просто удобный тестер, с помощью которого начинающие оптимизаторы смогут кидаться друг в друга результами тестирования кода на разных машинах, и кажется наконец оно получилось ;)
    Протокол дописывается в файл чтобы можно было протестить на нескольких машинах подряд.

    А существует API или cpuid функция для определения реальной тактовой частоты или только "метод dr_dred"?
     
  8. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    leo
    Увы "т.к. ffree не изменяет указатель вершины стека" противоречит тому, что "fstp st и ffree st эквивалентны с точки зрения результата", и замена fstp на ffree быстро приводит FPU стек в полную непригодость :dntknw:((
     
  9. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Y_Mur
    Противоречит, если вырывать цитаты из контекста ;) Вообще-то речь шла о полной очистке стека FPU и в этом смысле fstp и ffree очищают регистры одинаково успешно, если конечно кому то не придет в голову после ffree использовать fstp или другие операции с инвалидным регистром (кроме fld ес-но)
     
  10. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    leo
    Ага уже и сам понял, что полностью очищать стек ими можно ;), только мне пришло в голову заменить fstp на ffree когда над ним были занятые позиции, есно получил баг и запостил #68
     
  11. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    на моем стареньком PIII 855MГц тест Y_Mur-а из поста #67 вывел:
    посмотрим, что покажет этот же тест на Box Core 2 Duo E6600 2.40 Ghz :))
     
  12. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    итого, на моем новом Intel Core 2 Duo E6600 2400GHz (1066 MHz FSB 4MB L2 Cache), материнской P5B Deluxe LGA775 и гигом корсаровской оперативки тест Y_Mur-a из поста #67 выдал следующее: