| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- #pragma once
- #include <QDebug>
- #include <QThread>
- #ifdef __linux__
- #include <pthread.h>
- #include <sched.h>
- #endif
- namespace Render {
- class ThreadAffinity {
- public:
- static bool pin_to_core(QThread *thread, int core_id) {
- if (!thread) {
- qWarning() << "ThreadAffinity: null thread";
- return false;
- }
- #ifdef __linux__
- pthread_t native_thread =
- reinterpret_cast<pthread_t>(thread->currentThreadId());
- cpu_set_t cpuset;
- CPU_ZERO(&cpuset);
- CPU_SET(core_id, &cpuset);
- int result =
- pthread_setaffinity_np(native_thread, sizeof(cpu_set_t), &cpuset);
- if (result == 0) {
- return true;
- } else {
- qWarning() << "ThreadAffinity: Failed to pin thread to core" << core_id
- << "error:" << result;
- return false;
- }
- #else
- return false;
- #endif
- }
- static bool pin_current_thread_to_core(int core_id) {
- #ifdef __linux__
- cpu_set_t cpuset;
- CPU_ZERO(&cpuset);
- CPU_SET(core_id, &cpuset);
- int result =
- pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
- if (result == 0) {
- return true;
- } else {
- qWarning() << "ThreadAffinity: Failed to pin current thread, error:"
- << result;
- return false;
- }
- #else
- Q_UNUSED(core_id);
- return false;
- #endif
- }
- static bool pin_to_cores(QThread *thread, const std::vector<int> &core_ids) {
- if (!thread || core_ids.empty()) {
- qWarning() << "ThreadAffinity: invalid parameters";
- return false;
- }
- #ifdef __linux__
- pthread_t native_thread =
- reinterpret_cast<pthread_t>(thread->currentThreadId());
- cpu_set_t cpuset;
- CPU_ZERO(&cpuset);
- for (int core_id : core_ids) {
- CPU_SET(core_id, &cpuset);
- }
- int result =
- pthread_setaffinity_np(native_thread, sizeof(cpu_set_t), &cpuset);
- if (result == 0) {
- return true;
- } else {
- qWarning() << "ThreadAffinity: Failed to pin thread, error:" << result;
- return false;
- }
- #else
- Q_UNUSED(core_ids);
- return false;
- #endif
- }
- static int get_core_count() {
- #ifdef __linux__
- return static_cast<int>(sysconf(_SC_NPROCESSORS_ONLN));
- #else
- return QThread::idealThreadCount();
- #endif
- }
- static std::vector<int> get_current_affinity() {
- std::vector<int> cores;
- #ifdef __linux__
- cpu_set_t cpuset;
- CPU_ZERO(&cpuset);
- if (pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset) ==
- 0) {
- for (int i = 0; i < CPU_SETSIZE; ++i) {
- if (CPU_ISSET(i, &cpuset)) {
- cores.push_back(i);
- }
- }
- }
- #endif
- return cores;
- }
- static bool reset_affinity(QThread *thread) {
- if (!thread) {
- return false;
- }
- #ifdef __linux__
- pthread_t native_thread =
- reinterpret_cast<pthread_t>(thread->currentThreadId());
- cpu_set_t cpuset;
- CPU_ZERO(&cpuset);
- int core_count = get_core_count();
- for (int i = 0; i < core_count; ++i) {
- CPU_SET(i, &cpuset);
- }
- int result =
- pthread_setaffinity_np(native_thread, sizeof(cpu_set_t), &cpuset);
- return result == 0;
- #else
- Q_UNUSED(thread);
- return false;
- #endif
- }
- struct AffinityStrategy {
- int render_core{-1};
- int main_core{-1};
- std::vector<int> worker_cores;
- static AffinityStrategy auto_detect() {
- AffinityStrategy strategy;
- int core_count = get_core_count();
- if (core_count >= 8) {
- strategy.main_core = 0;
- strategy.render_core = 1;
- strategy.worker_cores = {2, 3};
- } else if (core_count >= 4) {
- strategy.main_core = 0;
- strategy.render_core = 2;
- strategy.worker_cores = {1, 3};
- } else {
- strategy.main_core = -1;
- strategy.render_core = -1;
- }
- return strategy;
- }
- };
- };
- } // namespace Render
|