Кэширование

Тема в разделе "Машинное отделение", создана пользователем WildCat, 21 авг 2009.

  1. TopicStarter Overlay

    WildCat Коршунов Игорь

    • Команда форума
    Рег.:
    04.05.2006
    Сообщения:
    3.599
    Симпатии:
    4
    Репутация:
    0
    Адрес:
    Гомель
    Оффлайн
    Недавно выяснилось, что при частых обращения к большим таблицам заметно страдает быстродействие. Скорее всего из-за того, что кэш оказывается забит мусором из этих таблиц.

    Есть ли какой способ запретить кэширование процессором конкретного массива?
  2. Tsukrov Учаcтник

    • Участник
    Рег.:
    11.08.2007
    Сообщения:
    65
    Симпатии:
    0
    Репутация:
    0
    Оффлайн
    Когда-то пришел к аналогичным выводам.
    Можно запретить кэширование памяти при выделении её VirtualAlloc.

    Если речь идет о Win-дозе.
  3. dmchess Зарегистрирован

    Рег.:
    29.10.2006
    Сообщения:
    5
    Симпатии:
    0
    Репутация:
    0
    Оффлайн
    1. Если данные засоряют L2 кеш процессора, то перед тем, как их читать можно выполнить _mm_prefetch((addr,_MM_HINT_NTA), (это для VisualStudio), тогда данные из памяти будут читаться в L2 только в один банк L2, остальной объем кеша не будет засорятся.
    2. Доступ к памяти на уровне процессора происходит по страницам, размером обычно 4Кб, чтобы получить доступ к странице процессор получает доступ к дескриптору страницы, если он не загружен в кеш, то нужно выполнить довольно много действий, чтобы его подгрузить. К тому же если страниц много, дескрипторы тоже засоряют кеш. Специально для таких случаев в windows есть понятие Large Pages (можно использовать, вызвав VirtualAlloc с ключом MEM_LARGE_PAGES, но реально работает только в Windows Server), в Linux называются Huge Pages и настройка работает для всей системы. Размер страницы в этом случае становится 2-4Mb, и приложения, использующие частый доступ к случайным участкам большого массива памяти могут работать процентов на 30% быстрее
  4. TopicStarter Overlay

    WildCat Коршунов Игорь

    • Команда форума
    Рег.:
    04.05.2006
    Сообщения:
    3.599
    Симпатии:
    4
    Репутация:
    0
    Адрес:
    Гомель
    Оффлайн
    Короче, картина такая.
    Параллельно с работой основного алгоритма происходит запись/чтение данных в массив (в основном по случайным адресам, т.к. этот массив это хеш-таблица).

    Включение/выключение кэша делаю так:
    Код:
      EvalHash = (unsigned __int64 *) VirtualAlloc(0, EVAL_SIZE * 8, MEM_COMMIT, PAGE_READWRITE | PAGE_NOCACHE);
    //EvalHash = (unsigned __int64 *) VirtualAlloc(0, EVAL_SIZE * 8, MEM_COMMIT, PAGE_READWRITE);
    
    Размер массива 65536 байт: с включенным кэшем время работы программы 15.1 сек, без кэша - 19.7.
    Размер - 16777216: вкл - 16.9, выкл - 21.4.

    Почему с увеличением размера массива увеличивается время выполнения программы (даже с выключенным кэшем)? Размер массива никак не влияет на логику работы алгоритма, т.к. данные из массива только читаются/записываются, но никак не используются в программе.
  5. dmchess Зарегистрирован

    Рег.:
    29.10.2006
    Сообщения:
    5
    Симпатии:
    0
    Репутация:
    0
    Оффлайн
    Потому-что, при увеличении размера массива растет кол-во страниц памяти под этот массив, увеличивается вероятность отсутствия дескриптора нужной страницы памяти в DTLB, в виду того что они все туда не влезают, а его загрузка занимает продолжительное время, что и сказывается на времени работы программы.
  6. TopicStarter Overlay

    WildCat Коршунов Игорь

    • Команда форума
    Рег.:
    04.05.2006
    Сообщения:
    3.599
    Симпатии:
    4
    Репутация:
    0
    Адрес:
    Гомель
    Оффлайн
    Не совсем понятно как включить поддержку Large Pages.

    Похоже для 32-битных приложений эта фишка не работает.
  7. dmchess Зарегистрирован

    Рег.:
    29.10.2006
    Сообщения:
    5
    Симпатии:
    0
    Репутация:
    0
    Оффлайн
    Уточнение: не поддерживается 32 битное приложения для Itanium. Для x86 должно работать (если процессор поддерживает такую возможность), например в 7Zip можно включить поддержку Large Pages, есть утилита 7-max, которая перехватывает обращения по выделению памяти и делает Large Pages для этих обращений. Пишут, что получается существенное ускорение. В других источниках пишут, что эта фича работает только на Windows Server. На моем компьютере (Windows7-64, Windows Vista-64) поддержка Large Pages не включается. VirtualAlloc с ключом MEM_LARGE_PAGES возвращает NULL. Перевод кода ошибки - 'недостаточно ресурсов для операции'. Поиск дал результат, что это потому-что память в windows фрагментируется с течением времени, и она просто не находит свободные блоки такого размера.
  8. TopicStarter Overlay

    WildCat Коршунов Игорь

    • Команда форума
    Рег.:
    04.05.2006
    Сообщения:
    3.599
    Симпатии:
    4
    Репутация:
    0
    Адрес:
    Гомель
    Оффлайн
    Хотелось бы какое-то универсальное решение, а не то, что работает только под одной конкретной ОС.
  9. bankuss Александр

    • Заслуженный
    • Участник
    • Старожил
    Рег.:
    24.05.2006
    Сообщения:
    1.084
    Симпатии:
    38
    Репутация:
    6
    Оффлайн
    LARGE_PAGES - тоже искал инфу по винде, так ничего хорошего и не нашел...
    зато в Linux эта штука работает. как пишут, рыбка3 прибавляет до 20% в скорости в этом режиме.
  10. Shark Учаcтник

    • Участник
    Рег.:
    30.06.2007
    Сообщения:
    124
    Симпатии:
    0
    Репутация:
    0
    Адрес:
    Барнаул
    Оффлайн
    PAGE_NOCACHE - насколько я понимаю не имеет отношения к кэш памяти процессора. Это кэш страниц виртуальной памяти.
  11. TopicStarter Overlay

    WildCat Коршунов Игорь

    • Команда форума
    Рег.:
    04.05.2006
    Сообщения:
    3.599
    Симпатии:
    4
    Репутация:
    0
    Адрес:
    Гомель
    Оффлайн
    В MSDN этот момент как-то нечетко прописан. Но, если бы это было отключение кэша страниц виртуальной памяти, то никакого падение скорости установка этого флага дать не могла. У меня же падение было очень существенным.

Поделиться этой страницей