Skip to content

avoid too high number of threads on multi socket system and with HT#4223

Open
dtrawins wants to merge 4 commits into
mainfrom
tune_threads
Open

avoid too high number of threads on multi socket system and with HT#4223
dtrawins wants to merge 4 commits into
mainfrom
tune_threads

Conversation

@dtrawins
Copy link
Copy Markdown
Collaborator

@dtrawins dtrawins commented May 19, 2026

🛠 Summary

Problems to solve:
on dual socket host with HT, number of threads was too high in latency model. Optimal is number of physical cores on one socket.
Without docker on linux, OV should apply all defaults
When container has quota, number of threads should be like number of allocated cores.

🧪 Checklist

  • Unit tests added.
  • The documentation updated.
  • Change follows security best practices.
    ``

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces additional CPU-topology detection utilities and updates OpenVINO CPU default property selection to reduce excessive thread counts (especially on multi-socket / hyper-threaded systems) when running under Linux containers.

Changes:

  • Added Linux helpers to detect physical CPU cores and socket count via /proc/cpuinfo.
  • Updated applyDefaultCpuProperties() to apply container-aware defaults (pinning, streams, and thread count) based on performance hint and detected topology.
  • Changed error handling in applyDefaultCpuProperties() to log warnings instead of failing with an error status.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
src/systeminfo.hpp Declares new Linux CPU-topology helper APIs (physical cores, sockets).
src/systeminfo.cpp Implements CPU-topology detection by parsing /proc/cpuinfo.
src/ov_utils.cpp Adjusts default OpenVINO CPU properties in Docker, including thread-count logic based on topology.

Comment thread src/systeminfo.cpp
Comment thread src/systeminfo.cpp Outdated
Comment on lines +157 to +190
uint16_t getNumberOfPhysicalCores() {
std::set<std::string> uniqueCores;
std::ifstream cpuInfo("/proc/cpuinfo");
if (!cpuInfo.is_open()) {
return std::max<uint16_t>(static_cast<uint16_t>(std::thread::hardware_concurrency()), 1);
}
std::string line;
while (std::getline(cpuInfo, line)) {
if (line.find("core id") != std::string::npos) {
uniqueCores.insert(line);
}
}
if (uniqueCores.empty()) {
return std::max<uint16_t>(static_cast<uint16_t>(std::thread::hardware_concurrency()), 1);
}
return static_cast<uint16_t>(uniqueCores.size());
}

uint16_t getNumberOfSockets() {
std::set<std::string> uniqueSockets;
std::ifstream cpuInfo("/proc/cpuinfo");
if (!cpuInfo.is_open()) {
return 1;
}
std::string line;
while (std::getline(cpuInfo, line)) {
if (line.find("physical id") != std::string::npos) {
uniqueSockets.insert(line);
}
}
if (uniqueSockets.empty()) {
return 1;
}
return static_cast<uint16_t>(uniqueSockets.size());
Comment thread src/ov_utils.cpp
Comment on lines 155 to +159
try {
const uint16_t coreCount = getCoreCount();
const uint16_t sanitizedCoreCount = coreCount > 0 ? coreCount : 1;

if (properties.find(ov::inference_num_threads.name()) == properties.end()) {
properties[ov::inference_num_threads.name()] = static_cast<int>(sanitizedCoreCount);
SPDLOG_DEBUG("applyDefaultCpuProperties: setting inference_num_threads to {}", sanitizedCoreCount);
if (!isRunningInDocker()) {
return StatusCode::OK;
}
const uint16_t coreCount = getCoreCount();
Comment thread src/ov_utils.cpp Outdated
Comment on lines +189 to +190
const uint16_t sockets = getNumberOfSockets();
numThreads = std::max(1, static_cast<int>(getNumberOfPhysicalCores() / sockets));
Comment thread src/ov_utils.cpp
Comment on lines 195 to 199
} catch (const std::exception& ex) {
SPDLOG_ERROR("Exception while applying default CPU properties: {}", ex.what());
return StatusCode::INTERNAL_ERROR;
SPDLOG_WARN("Exception while applying default CPU properties: {}", ex.what());
} catch (...) {
SPDLOG_ERROR("Unknown exception while applying default CPU properties");
return StatusCode::INTERNAL_ERROR;
SPDLOG_WARN("Unknown exception while applying default CPU properties");
}
@dtrawins dtrawins added this to the 2026.2_rc milestone May 19, 2026
Comment thread src/ov_utils.cpp
if (!isRunningInDocker()) {
return StatusCode::OK;
}
const uint16_t coreCount = getCoreCount();
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for >0 check?

Comment thread src/systeminfo.cpp
return std::max<uint16_t>(static_cast<uint16_t>(std::thread::hardware_concurrency()), 1);
}
std::string line;
while (std::getline(cpuInfo, line)) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we treat cpu info file as trusted?
We read, iterate and load lines to memory so potentially malicious cpu info could overflow memory.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants