Сравнение чисел в ММХ

Тема в разделе "WASM.ASSEMBLER", создана пользователем SolarWarez, 8 дек 2004.

  1. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    leo >




    Assembly/Compiler Coding Rule 27. (H impact, L generality) Always put

    code and data on separate pages.
    Avoid self-modifying code wherever possible.

    If code is to be modified, try to do it all at once and make sure the code that

    performs the modifications and the code being modified are on separate 4 KB

    pages or on separate aligned 1 KB subpages.
     
  2. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    Теоретически незнаю, а практически разнос кода и данных с выравниванием на 1Кб-4Кб ничего не улучшил, более точный замер (160 тиков против 162) получил, если кроме выравнивания основного цикла next: на 16, ещё выровнять testloop: на 4. Даже не 160, а 153 если выкинуть 14 nop'ов (для выравнивания на 16 и участвующие в тестировании), они идут 2 за такт
     
  3. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    Вот интересный тест (инструкция "mov eax,[mem]" при первом проходе), показывающий, что расположение данных в отдельной секции, иногда может стоить более миллиона тактов! (тестил на w2ksp4)



    В зависимости от того, где расположен mem, эта инструкция может выполнятся за 1 такт, за несколько сотен тактов, за несколько десятков тысяч, а иногда за много сот тысяч тактов (даже за миллион), и это при том, что mem выровнен.
    Код (Text):
    1. ----------------------------------------------------
    2. "1.exe"      "100.exe"    "10000.exe"  "100000.exe"
    3. ----------------------------------------------------
    4. 0000000001   0000000165   0000026265   0021191825
    5. 0000000001   0000000001   0000000001   0000000001
    6. 0000000001   0000000001   0000000001   0000000001
    7. 0000000001   0000000001   0000000001   0000000001
    8. 0000000001   0000000001   0000000001   0000000001
    9. 0000000001   0000000001   0000000001   0000000001
    10. 0000000001   0000000001   0000000028   0000000031
    11. 0000000001   0000000001   0000000001   0000000001
    12. 0000000001   0000000001   0000000001   0000000001
    13. 0000000001   0000000001   0000000001   0000000001
    14. ----------------------------------------------------
    15. OK           OK           OK           OK
    16. ----------------------------------------------------


    [​IMG] 518746522__memtest.zip
     
  4. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    S_T_A_S_

    Вот, вот, я тоже в конце концов набрел на этот рул. И чуть дальше тоже четко сказано: "Software should avoid writing to a code page in the same 1 KB subpage of that is being executed".



    bogrus > "практически разнос кода и данных с выравниванием на 1Кб-4Кб ничего не улучшил"

    Это видимо на P2,P3 (P6 family). А для P4 речь идет не столько о выравнивании, сколько именно о разносе изменяемых данных и кода. В рассматриваемом случае исполняемый кусок кода не должен производить запись в пределах текущего килобайта адресного пространства - иначе огромные штрафы и пенальти.



    Интел как всегда не все договаривает, но после копания в мануалах я понял примерно следующее. И в P6 family и в P4 осуществляется контроль записи в кэш на предмет модификации кода. При обнаружении такой записи соответвующие строки кэша помечаются как модифицированные и инвалидные. А вот дальнейшие действия различаются в зависимости от семейства процессора и "дальности" от\до исполняемого кода. В P6 family инструкции выбираются 16-байтными блоками из одной или двух (при перекрытии) 32-байтных строк кэша и декодируются "на лету". Если происходит модификация внутри текущего блока или ближайших, готовящихся к загрузке, то получаем печальные последствия в смысле задержки (сброс конвейера и invalidate cache line). Но в нашем случае микса данных и кода ничего страшного не происходит, если в предах 32-64 байт кода не происходит запись в эти же линии кэша. В P4 ситуация иная, т.к. помимо кэширования данных и кода в L2, в L1 кэшируются декодированные микрооперации и интелы при записи по адресам уже декодированного кода не придумали ничего лучшего, как делать invalidate всего trace cache ("a write or a snoop of an instruction in a code segment, where the target instruction is already decoded and resident in the trace cache, invalidates the entire trace cache"). Звучит как приговор окончательный, но потом в optimization находим смягчающие обстоятельства - упомянутое правило №27: оказывается достаточно не модифицировать данные или код в одном килобайтном блоке с исполняемым кодом. Что собственно и подтверждается практикой.