vak: (Default)
[personal profile] vak
Судя по комментам к предыдущему посту, существует устойчивое подозрение, что сопрограммы имеют стек, и вообще кушают ресурсы. Хорошо, давайте померяем, это нетрудно. Создадим миллион сопрограмм и глянем расход памяти. Вот такой тестик.
co_void_t print(int n)
{
for (;;) {
std::cout << n << std::endl;
co_await co_await_t{};
}
}

int main(int argc, char **argv)
{
std::coroutine_handle<> continuation[1000000];

std::cout << "Using " << mallinfo().uordblks << " bytes after start.\n";

for (int i = 0; i < 1000000; i++)
continuation[i] = print(i);

std::cout << "Using " << mallinfo().uordblks << " bytes after coroutine allocation.\n";

for (int i = 0; i < 1000000; i++)
continuation[i].resume();

std::cout << "Using " << mallinfo().uordblks << " bytes after coroutine run.\n";

for (int i = 0; i < 1000000; i++)
continuation[i].destroy();

std::cout << "Using " << mallinfo().uordblks << " bytes after coroutine destroyed.\n";
return 0;
}
Результат:
Using 77488 bytes after start.
Using 48077488 bytes after coroutine allocation.
0
...
999999
Using 48077488 bytes after coroutine run.
Using 77824 bytes after coroutine destroyed.
Делим разницу на количество сопрограмм: (48077488 - 77488) / 1000000 = 48 байтов на одну сопрограмму. Вполне недорогое удовольствие получается. Конечно, никакого собственного стека у сопрограмм не имеется, просто негде.

Date: 2021-06-22 03:50 (UTC)
ircicq: (Default)
From: [personal profile] ircicq
Стек - это прежде всего структура вида LIFO.
А как она реализована: сплошной массив у Threads, или список фреймов в Heap у coroutines - частности.

В любом случае где-то хранится цепь continuations вместо цепочки return addresses.


Date: 2021-06-22 05:13 (UTC)
sab123: (Default)
From: [personal profile] sab123
Не копируется. На стек (или скорее даже в регистр, как аргумент вызова) кладется указатель на контекст. Точно так же, как и в лямбде. На стеке резервируются только краткоживущие локальные переменные.