我想知道是否有办法在特定的NUMA节点上创建线程堆栈。 我已经编写了这段代码,但我不确定它是否能解决问题。
pthread_t thread1;
int main(int argc, char**argv) {
pthread_attr_t attr;
pthread_attr_init(&attr);
char** stackarray;
int numanode = 1;
stackarray = (char**) numa_alloc_onnode(sizeof(char*), numanode);
// considering that the newly
// created thread will be running on a core on node1
pthread_attr_setstack(&attr, stackarray[0], 1000000);
pthread_create(&thread1, &attr, function, (void*)0);
...
...
}
感谢您的帮助
答案 0 :(得分:1)
这是我用于此的代码(稍微适合删除其他地方定义的一些常量)。请注意,我首先正常创建线程,然后从线程内调用下面的SetAffinityAndRelocateStack()
。我认为这比尝试创建自己的堆栈要好得多,因为堆栈特别支持增长,以防达到底部。
代码也可以适用于从外部对新创建的线程进行操作,但是这可能会导致竞争条件(例如,如果线程在其堆栈中执行I / O),所以我不推荐它。 / p>
void* PreFaultStack()
{
const size_t NUM_PAGES_TO_PRE_FAULT = 50;
const size_t size = NUM_PAGES_TO_PRE_FAULT * numa_pagesize();
void *allocaBase = alloca(size);
memset(allocaBase, 0, size);
return allocaBase;
}
void SetAffinityAndRelocateStack(int cpuNum)
{
assert(-1 != cpuNum);
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(cpuNum, &cpuset);
const int rc = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
assert(0 == rc);
pthread_attr_t attr;
void *stackAddr = nullptr;
size_t stackSize = 0;
if ((0 != pthread_getattr_np(pthread_self(), &attr)) || (0 != pthread_attr_getstack(&attr, &stackAddr, &stackSize))) {
assert(false);
}
const unsigned long nodeMask = 1UL << numa_node_of_cpu(cpuNum);
const auto bindRc = mbind(stackAddr, stackSize, MPOL_BIND, &nodeMask, sizeof(nodeMask), MPOL_MF_MOVE | MPOL_MF_STRICT);
assert(0 == bindRc);
PreFaultStack();
// TODO: Also lock the stack with mlock() to guarantee it stays resident in RAM
return;
}