Имитация локальных переменных потока

Я хочу смоделировать локальные переменные потока для нестатических членов, что-то вроде этого:

template< typename T, unsigned int tNumThread >
class ThreadLocal
{
private:

protected:
T mData[tNumThread];

unsigned int _getThreadIndex()
{
return ...; // i have a threadpool and each thread has an index from 0 to n
}

public:
ThreadLocal() {};
~ThreadLocal() {};

T& operator ->()
{
return mData[_getThreadIndex()];
}
...
};

Но проблема в том, что номер потока будет определен во время выполнения, и я должен выделить mData из кучи.

Я хочу знать, есть ли способ не использовать выделение из кучи и использовать обычный массив, как указано выше?

0

Решение

Каждый поток имеет свой собственный стек, и помните, что кадры стека выталкиваются (или могут рассматриваться как выталкивающие), когда функция возвращается.

Вот почему у нас есть «Python без стеков», потому что 1 стек (что нужно Python) и несколько потоков не играют хорошо (см. Глобальную блокировку интерпретатора)

Вы можете поместить его в main, это будет длиться долго, но помните, что C (++) хочет знать все размеры в COMPILE TIME, поэтому, если число потоков изменяется (не фиксируется в COMPILE TIME), нет способа узнать это.

Что вам действительно нужно, так это что-то не основное, но это не шаблон (по числу), потому что это число не может быть известно во время компиляции.

Есть функция выделения стека (например, malloc), которую предоставляет GCC, но я не могу ее найти, хотя лучше избегать ее использования, потому что тогда оптимизации действительно работают.

Точно так же не стоит недооценивать возможности упреждающего чтения ваших процессоров и оптимизации GCC, если поместить массив в кучу, это неплохо.

Интересно читать с хорошими картинками, но, к сожалению, только отдаленно связанные с темой:
http://www.nongnu.org/avr-libc/user-manual/malloc.html

1

Другие решения

Я предлагаю:

std::unordered_map<std::thread::id, T, stackalloc> myTLS;

Либо вы заблокируете все доступы, либо подготовите популяцию заранее и получите доступ к ней только для чтения позже.

Вы можете использовать его в сочетании с распределителем стека.

typedef short_alloc<pair<const thread::id, T>, maxthrds> stackalloc;

https://howardhinnant.github.io/stack_alloc.html

Если вы хотите другое решение, здесь вы можете сделать:

struct Padder
{
T t;
char space_[128 - sizeof(T)];  // if sizeof(T) >= 128 just don't include the padding.
};

std::array<Padder, maxthreads> myTLS;

Для MESI доступ без узких мест.
С помощью этого метода вам нужно будет следить за тем, чтобы ваши потоки имели собственный индекс в этом массиве.

0

По вопросам рекламы [email protected]