Существует ли проблема с отскоком строк в кэше, когда потоки выполняются последовательно на общих объектах? - PullRequest
0 голосов
/ 25 апреля 2020

Таким образом, у моей программы есть такой сценарий:

//Main thread doing something on request
request.setContext(foo1);
....
//start a side thread for a task, the thread has access to the request structure
startThread(task, &request);
.....
//whatever is done on side thread will happen before completion callback is called
memory_barrier();
thread_complete_callback(task1, &request);
//In main thread it will be reading the change made to request from task1
request.getContext(bar1);

request.setContext(foo2);
startThread(task2, &request);
....

И во время выполнения побочного потока она также может изменить вещи по запросу:

//this is inside the side thread
request->setContext(bar1); 

Поэтому я использую многопоточность для тяжелых IO работает и освобождает работников основного потока для обслуживания других запросов. Но для этого конкретного запроса все делается последовательно. Он переходит из основного потока в поток 1 для выполнения задачи 1, а когда он возвращается, затем идет в поток 2 для выполнения задачи 2. Никогда не будет времени, когда к запросу обращается основной поток или любой другой поток одновременно.

Итак, в этом случае все еще остается типичная проблема Отскок строк кэша ? Разве это нормально - разделять мой объект запроса среди множества разных потоков, если на нем одновременно не работают ни один из двух потоков?

Пожалуйста, дайте мне знать, если мой анализ здесь верный или нет :

  • Переключение из основного потока в боковой поток, побочный поток пытается записать некоторые данные для запроса, поэтому он выбирает эту строку кэша из ОЗУ, устанавливая эту строку в главном потоке в Shared штат. Затем он пишет новое значение для него. Но это автоматически сделает недействительными аналоги в кеше основного потока , даже если в основном потоке еще не происходит чтение?

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

  • Боковая резьба сделана и больше не нужна. Вернитесь к основной теме. Новые данные стороннего потока по запросу будут записаны в ОЗУ.

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

В качестве альтернативы, я могу просто наложить больше ограничений на мой код, чтобы побочный поток НЕ касался объекта запроса (но это сильно затрудняет кодирование). В этом случае:

  • В боковой ветке все изменения, которые мне нужно внести в запрос, будут сохранены в отдельной структуре.

  • Сторона нить сделана. Вернитесь к основному потоку, эта структура передается, чьи данные записываются в ОЗУ.

  • Основной поток (или обратный вызов завершения потока, тоже самое) загрузит данные в структуре из ОЗУ в кэш и скопирует их в свою структуру запроса в кеше.

  • Главный поток должен прочитать эти данные обратно, теперь он может читать их из кэша L1.

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

Так что это должно быть довольно минимальными издержками? Это правильно?

Однако есть одна загвоздка. Если, не разделив объект между потоками, я смогу минимизировать / сгладить данные, хранящиеся в структуре между потоками, тогда это уменьшит нагрузку на ОЗУ, когда я вернусь в основной поток. Например, вместо того, чтобы копировать все контейнеры и объект std :: string по запросу из кэша бокового потока в кэш основного потока, я мог бы хранить все строки как литералы const char * в структуре между потоками. Это будет экономия, верно?

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