Практические ограничения на предварительную выборку большого количества справочных данных - PullRequest
2 голосов
/ 18 июня 2019

Я собираюсь сделать следующее:

  • Создать процесс демона, который создает около 50 КБ справочных данных и сохраняет его в массиве в общей памяти.
  • Процесс демона будетего привязка установлена ​​на одно ядро ​​в сокете и будет периодически вызывать __builtin_prefetch() по адресу каждого 64-го байта справочных данных, чтобы сохранить все справочные данные в кэше L3 для всех процессов, работающих на других ядрах в одном сокете.
  • Несколько раз в секунду процессы приложения будут индексироваться в массиве для получения любого эталонного значения, в котором они нуждаются в это время.Поскольку данные будут в кеше L3, время доступа будет относительно коротким.

Я предполагаю, что я не первый, кто приходит с такой идеей.Кто-нибудь может дать совет по поводу ограничений, с которыми я могу столкнуться?Например, рассмотрим следующий псевдокод в процессе демона для хранения эталонных данных в кэше:

for (size_t i = 0; i < sizeof(referenceData); i += 64) {
    __builtin_prefetch(i + (void*)&referenceData);
}

Для эталонных данных размером 50 КБ вышеуказанный цикл будет вызывать __builtin_prefetch() 800 раз в быстрой последовательности.Может ли это вызвать проблемы, такие как скачки задержки, когда другие приложения пытаются получить доступ к памяти (кроме справочных данных)?Если это так, я мог бы вставить оператор сна в цикл for:

for (size_t i = 0; i < sizeof(referenceData); i += 64) {
    __builtin_prefetch(i + (char*)&referenceData);
    if (i % (64*10)) { // sleep every 10th time around the loop
        sleep_briefly();
    }
}

Полезны советы и ссылки на соответствующие источники документа.

Редактировать, чтобы добавить дополнительную информацию на основев комментариях :

  • Справочные данные не изменятся.Другие процессы получат доступ к небольшому подмножеству данных в событии уровня приложения: вероятно, около 7 индексов данных, каждый индекс извлекает 4 байта, таким образом, получая около 28 байтов за событие.

  • Я не думаю, что будет возможно предсказать, какие записи данных наиболее вероятно будут доступны, поэтому я хотел бы сохранить все эталонные данные в кэше, а не просто в небольшом подмножестве.

  • Если задержка не имеет значения, то не будет необходимости в кэшированных справочных данных, поскольку каждое приложение может пересчитывать все, что ему нужно, по мере необходимости для каждого события.Однако задержка ответа на события имеет значение.

  • Я еще не разработал весь код приложения, но я ожидаю, что время "ответа на событие" будет меньше 200 нс без этой оптимизации.Если эта оптимизация работает хорошо, то она может сократить время «ответа на событие» до менее 100 нс.

  • События могут происходить, возможно, несколько сотен раз в секундуили так редко, как раз в несколько секунд.Поэтому меня беспокоит то, что если эталонные данные не хранятся в кэше активно, иногда они будут выгружаться из кэша из-за неиспользования.

1 Ответ

1 голос
/ 18 июня 2019

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

Ваш процесс, топящий кеш процессора, вообще не выглядит разумным.

В Intel вы можете использовать Технология выделения кэша , чтобы зарезервировать определенный объем кэша L3 для ваших приложений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...