1
0
Fork 0

linux processor affinity

This commit is contained in:
Frank Celler 2015-05-28 14:51:32 +02:00
parent f5f8afea22
commit c2db22e379
12 changed files with 136 additions and 33 deletions

View File

@ -344,12 +344,12 @@ ArangoServer::ArangoServer (int argc, char** argv)
_queryRegistry(nullptr),
_pairForAql(nullptr),
_indexPool(nullptr),
_threadAffinity(true) {
_threadAffinity(1) {
TRI_SetApplicationName("arangod");
#ifndef TRI_HAVE_THREAD_AFFINITY
_threadAffinity = false;
_threadAffinity = 0;
#endif
// set working directory and database directory
@ -536,7 +536,7 @@ void ArangoServer::buildApplicationServer () {
("no-server", "do not start the server, if console is requested")
#ifndef TRI_HAVE_THREAD_AFFINITY
("use-thread-affinity", &_threadAffinity, "try to set thread affinity")
("use-thread-affinity", &_threadAffinity, "try to set thread affinity (0=disable, 1=disjunct, 2=overlap)")
#endif
;
@ -561,7 +561,7 @@ void ArangoServer::buildApplicationServer () {
#ifdef TRI_HAVE_THREAD_AFFINITY
additional["General Options:help-admin"]
("use-thread-affinity", &_threadAffinity, "try to set thread affinity")
("use-thread-affinity", &_threadAffinity, "try to set thread affinity (0=disable, 1=disjunct, 2=overlap)")
;
#endif
@ -1013,18 +1013,20 @@ int ArangoServer::startupServer () {
size_t n = TRI_numberProcessors();
if (n > 2) {
if (_threadAffinity) {
if (n > 2 && _threadAffinity > 0) {
size_t ns = _applicationScheduler->numberOfThreads();
size_t nd = _applicationDispatcher->numberOfThreads();
if (ns != 0 && nd != 0) {
LOG_INFO("the server has %d (hyper) cores, using %d scheduler threads, %d dispatcher threads",
(int) n, (int) ns, (int) nd);
}
else {
_threadAffinity = 0;
}
vector<size_t> ps;
vector<size_t> pd;
switch (_threadAffinity) {
case 1:
if (n < ns + nd) {
ns = round(1.0 * n * ns / (ns + nd));
nd = round(1.0 * n * nd / (ns + nd));
@ -1039,14 +1041,37 @@ int ArangoServer::startupServer () {
}
}
size_t i = 0;
break;
for (; i < ns; ++i) {
case 2:
if (n < ns) {
ns = n;
}
if (n < nd) {
nd = n;
}
break;
default:
_threadAffinity = 0;
break;
}
if (_threadAffinity > 0) {
TRI_ASSERT(ns <= n);
TRI_ASSERT(nd <= n);
vector<size_t> ps;
vector<size_t> pd;
for (size_t i = 0; i < ns; ++i) {
ps.push_back(i);
}
for (; i < ns + nd; ++i) {
pd.push_back(i);
for (size_t i = 0; i < nd; ++i) {
pd.push_back(n - i - 1);
}
_applicationScheduler->setProcessorAffinity(ps);
@ -1055,7 +1080,6 @@ int ArangoServer::startupServer () {
LOG_INFO("scheduler cores: %s, dispatcher cores: %s",
to_string(ps).c_str(), to_string(pd).c_str());
}
}
else {
LOG_INFO("the server has %d (hyper) cores", (int) n);
}

View File

@ -638,7 +638,7 @@ namespace triagens {
/// @brief use thread affinity
////////////////////////////////////////////////////////////////////////////////
bool _threadAffinity;
uint32_t _threadAffinity;
};
}
}

View File

@ -72,10 +72,14 @@
#include <time.h>
#ifdef TRI_HAVE_POSIX_THREADS
#ifdef _GNU_SOURCE
#include <pthread.h>
#else
#define _GNU_SOURCE
#include <pthread.h>
#undef _GNU_SOURCE
#endif
#endif
#ifdef TRI_HAVE_PROCESS_H
#include <process.h>

View File

@ -103,7 +103,8 @@ Thread::Thread (std::string const& name)
_finishedCondition(nullptr),
_started(0),
_running(0),
_joined(0) {
_joined(0),
_affinity(-1) {
TRI_InitThread(&_thread);
}
@ -187,6 +188,10 @@ bool Thread::start (ConditionVariable * finishedCondition) {
LOG_ERROR("could not start thread '%s': %s", _name.c_str(), strerror(errno));
}
if (0 <= _affinity) {
TRI_SetProcessorAffinity(&_thread, (size_t) _affinity);
}
return ok;
}
@ -258,7 +263,7 @@ int Thread::shutdown () {
////////////////////////////////////////////////////////////////////////////////
void Thread::setProcessorAffinity (size_t c) {
TRI_SetProcessorAffinity(&_thread, c);
_affinity = (int) c;
}
// -----------------------------------------------------------------------------

View File

@ -259,6 +259,12 @@ namespace triagens {
volatile sig_atomic_t _joined;
////////////////////////////////////////////////////////////////////////////////
/// @brief processor affinity
////////////////////////////////////////////////////////////////////////////////
int _affinity;
};
}
}

View File

@ -234,12 +234,12 @@ void TRI_SetProcessorAffinity (TRI_thread_t* thread, size_t core) {
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(c, &cpuset);
CPU_SET(core, &cpuset);
int s = pthread_setaffinity_np(*thread, sizeof(cpu_set_t), &cpuset);
if (s != 0) {
LOG_ERROR("cannot set affinity to core %d: %s", core, strerror(errno));
LOG_ERROR("cannot set affinity to core %d: %s", (int) core, strerror(errno));
}
#endif

View File

@ -162,7 +162,7 @@ void ApplicationDispatcher::buildAQLQueue (size_t nrThreads,
////////////////////////////////////////////////////////////////////////////////
size_t ApplicationDispatcher::numberOfThreads () {
return _nrStandardThreads + _nrAQLThreads;
return _nrStandardThreads /* + _nrAQLThreads */;
}
////////////////////////////////////////////////////////////////////////////////
@ -171,6 +171,7 @@ size_t ApplicationDispatcher::numberOfThreads () {
void ApplicationDispatcher::setProcessorAffinity (const vector<size_t>& cores) {
#ifdef TRI_HAVE_THREAD_AFFINITY
_dispatcher->setProcessorAffinity("STANDARD", cores);
#endif
}

View File

@ -355,6 +355,20 @@ void Dispatcher::reportStatus () {
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief sets the process affinity
////////////////////////////////////////////////////////////////////////////////
void Dispatcher::setProcessorAffinity (const string& name, const vector<size_t>& cores) {
auto const& it = _queues.find(name);
if (it == _queues.end()) {
return;
}
it->second->setProcessorAffinity(cores);
}
// -----------------------------------------------------------------------------
// --SECTION-- protected methods
// -----------------------------------------------------------------------------

View File

@ -178,6 +178,13 @@ namespace triagens {
void reportStatus ();
////////////////////////////////////////////////////////////////////////////////
/// @brief sets the process affinity
////////////////////////////////////////////////////////////////////////////////
void setProcessorAffinity (const std::string& name,
const std::vector<size_t>& cores);
// -----------------------------------------------------------------------------
// --SECTION-- protected methods
// -----------------------------------------------------------------------------

View File

@ -78,7 +78,9 @@ DispatcherQueue::DispatcherQueue (Scheduler* scheduler,
_gracePeriod(5.0),
_scheduler(scheduler),
_dispatcher(dispatcher),
createDispatcherThread(creator) {
createDispatcherThread(creator),
_affinityCores(),
_affinityPos(0) {
}
////////////////////////////////////////////////////////////////////////////////
@ -371,6 +373,21 @@ bool DispatcherQueue::isRunning () {
bool DispatcherQueue::startQueueThread () {
DispatcherThread * thread = (*createDispatcherThread)(this, _threadData);
if (! _affinityCores.empty()) {
size_t c = _affinityCores[_affinityPos];
LOG_INFO("using core %d for standard dispatcher thread", (int) c);
thread->setProcessorAffinity(c);
++_affinityPos;
if (_affinityPos >= _affinityCores.size()) {
_affinityPos = 0;
}
}
bool ok = thread->start();
if (! ok) {
@ -384,6 +401,14 @@ bool DispatcherQueue::startQueueThread () {
return ok;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief sets the process affinity
////////////////////////////////////////////////////////////////////////////////
void DispatcherQueue::setProcessorAffinity (const vector<size_t>& cores) {
_affinityCores = cores;
}
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------

View File

@ -165,6 +165,12 @@ namespace triagens {
return _name;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief sets the process affinity
////////////////////////////////////////////////////////////////////////////////
void setProcessorAffinity (const std::vector<size_t>& cores);
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
@ -353,6 +359,18 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
Dispatcher::newDispatcherThread_fptr createDispatcherThread;
////////////////////////////////////////////////////////////////////////////////
/// @brief cores to use for affinity
////////////////////////////////////////////////////////////////////////////////
std::vector<size_t> _affinityCores;
////////////////////////////////////////////////////////////////////////////////
/// @brief next affinity core to use
////////////////////////////////////////////////////////////////////////////////
size_t _affinityPos;
};
}
}

View File

@ -399,10 +399,10 @@ void ApplicationScheduler::setProcessorAffinity (const vector<size_t>& cores) {
#ifdef TRI_HAVE_THREAD_AFFINITY
size_t j = 0;
for (uint32_t i = 0; i < _nrSchedulerThreads) {
for (uint32_t i = 0; i < _nrSchedulerThreads; ++i) {
size_t c = cores[j];
LOG_INFO("using core %d for scheduler thread %d", c, i);
LOG_INFO("using core %d for scheduler thread %d", (int) c, (int) i);
_scheduler->setProcessorAffinity(i, c);
@ -412,7 +412,6 @@ void ApplicationScheduler::setProcessorAffinity (const vector<size_t>& cores) {
j = 0;
}
}
#endif
}