在一个特定的NUMA内存分配一个线程的堆栈(Allocating a Thread's St

2019-09-17 05:54发布

我想知道是否有一个特定的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);

  ...
  ...
}

谢谢您的帮助

Answer 1:

下面是我用这个(略适用于去除其他地方定义一些常量)的代码。 请注意,我通常先创建线程,然后调用SetAffinityAndRelocateStack()从内螺纹下方。 我想,这是不是试图创建自己的堆栈好得多,因为堆有在增长的情况下达到的底部特别支持。

该代码也可以适用于从外面新创建的线程上运行,但是这可能会引起竞争条件(例如,如果线程执行I / O到它的堆栈),所以我不会推荐它。

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;
}


文章来源: Allocating a Thread's Stack on a specific NUMA memory