Мы хотим обновить ОС на наших серверах от Ubuntu 10.04 LTS до Ubuntu 12.04 LTS. К сожалению, кажется, что латентность для запуска потока, который стал runnable, значительно увеличился с ядра 2.6 до ядра 3.2. На самом деле количество времени ожидания, которое мы получаем, трудно поверить.
Позвольте мне более конкретно про тест. У нас есть программа, которая запускает два потока. Первый поток получает текущее время (в тиках с использованием RDTSC), а затем сигнализирует переменную состояния один раз в секунду. Второй поток ожидает переменную условия и просыпается, когда она сигнализируется. Затем он получает текущее время (в тиках с использованием RDTSC). Разность между временем во втором потоке и временем в первом потоке вычисляется и отображается на консоли. После этого второй поток снова ждет переменную условия. Он будет сигнализирован снова первой нитью примерно через секунду.
Итак, в двух словах мы получим поток для обмена потоками через измерение задержки переменной состояния через секунду.
В ядре 2.6.32 эта латентность находится где-то порядка 2.8-3.5 мкс, что разумно. В ядре 3.2.0 эта латентность увеличилась примерно до 40-100 человек. Я исключил любые различия в оборудовании между двумя хостами. Они работают на идентичном оборудовании (двухсетевые процессоры X5687 {Westmere-EP}, работающие на частоте 3,6 ГГц, с отключением гиперпотока, скоростью и всеми состояниями C). Приложение-тест изменяет близость потоков для их запуска на независимых физических ядрах одного и того же сокета (т.е. Первый поток запускается на Core 0, а второй поток запускается на Core 1), поэтому нет отскока потоков на ядра или переключение/связь между сокетами.
Единственное различие между этими двумя хостами заключается в том, что на нем запущен Ubuntu 10.04 LTS с ядром 2.6.32-28 (переключатель быстрого контекстного контекста), а другой работает с последней версией Ubuntu 12.04 LTS с ядром 3.2.0-23 ( переключатель медленного контекстного контекста). Все настройки и оборудование BIOS идентичны.
Были ли какие-либо изменения в ядре, которые могли бы объяснить это смехотворное замедление в том, сколько времени требуется для запуска потока, который планируется запустить?
Update: Если вы хотите запустить тест на своем хосте и сборке linux, я отправил код в pastebin для вашего прочтения. Скомпилировать с помощью:
g++ -O3 -o test_latency test_latency.cpp -lpthread
Запустите с (если у вас есть хотя бы двухъядерный ящик):
./test_latency 0 1 # Thread 1 on Core 0 and Thread 2 on Core 1
Обновление 2: После многократного поиска параметров ядра, сообщений об изменениях ядра и личных исследований я выяснил, в чем проблема, и разместил решение в качестве ответа на этот вопрос.