LINUX.ORG.RU

[C][pool based memory allocator]

 


3

2

Подскажите какую-нибудь приличную сишную библиотеку для работы с памятью через пул объектов. Года 4 назад что-то находил, но название вылетело из головы совершенно.

Лицензия LGPL, BSD, etc...

★★★★★

Последнее исправление: mv (всего исправлений: 1)
Ответ на: комментарий от tailgunner

Это понятно. Непонятно другое - при обращении к другому объекту ты всё равно попадешь на другой TLB entry, так в чем профит? В одном месте сэкономил, в другом - потратил сэкономленное.

А другого объекта может и не быть.

mv ★★★★★
() автор топика
Ответ на: комментарий от mv

>> Это понятно. Непонятно другое - при обращении к другому объекту ты всё равно попадешь на другой TLB entry, так в чем профит? В одном месте сэкономил, в другом - потратил сэкономленное.

А другого объекта может и не быть.

Если его нет, то и границу страницы никто не пересечет :)

tailgunner ★★★★★
()

Можно поинтересоваться, что мешает от-mmap-ить кусок памяти и отщипывать от него необходимые буферы? Располагать участки рядом в (виртуальном) адресном пространестве легко, вычислить попадание на границу страниц - тоже.

staseg ★★★★★
()
Ответ на: комментарий от staseg

Написать всё самому ничто не мешает, кроме собственной лени и светлой надежды, что уже всё каким-то добряком давно написано.

mv ★★★★★
() автор топика
Ответ на: комментарий от mv

>>> А другого объекта может и не быть.

Если его нет, то и границу страницы никто не пересечет :)

С чего бы вдруг?

С того, что некому - другого объекта нет // К.О.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

С того, что некому - другого объекта нет // К.О.

А куда девать этот объект, который на границу страницы попался?

На вот тебе...

#include <stdio.h>
#include <stdint.h>
#include <sys/mman.h>
#include <assert.h>

uint64_t inline rdtsc()
{
    uint64_t ticks;

    asm volatile ("rdtsc\n"
                  "movl %%eax, (%%rsi)\n"
                  "movl %%edx, 4(%%rsi)\n"
                  :
                  :"S"(&ticks)
                  : "eax", "edx", "memory"
        );
    return ticks;
}

#define N 1280

int main()
{
    char *tmp;
    uint64_t *ptr, t1, t2;
    int i, j, k;

    tmp = mmap(0, 4096 * 2 * N, PROT_READ | PROT_WRITE,
                     MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0);
    assert(tmp != MAP_FAILED);
    ptr = (uint64_t *)tmp;
    for (j = 0; j < 2; j++, ptr = (uint64_t *)(tmp + 4092)) {
        uint64_t *ptr1 = ptr;
        t1 = rdtsc();
        for (k = 0; k < 1ULL<<8; k++) {
            for (ptr = ptr1, i = 0; i < N; i++, ptr += 4096 / 8)
                *ptr += 1;
        }
        t2 = rdtsc();
        printf("% 10ld\n", t2 - t1);
    }
    return 0;
}
$ ./123
  39282342
 258812631

mv ★★★★★
() автор топика
Ответ на: комментарий от tailgunner

Ну, блин, ленивый какой :) Исходник не дам, патч накладывай :-D

--- border.c    2010-09-14 00:34:19.200000379 +0200
+++ border32.c    2010-09-14 00:34:46.700000380 +0200
@@ -22,18 +22,19 @@
 int main()
 {
     char *tmp;
-    uint64_t *ptr, t1, t2;
+    uint32_t *ptr;
+    uint64_t t1, t2;
     int i, j, k;
 
     tmp = mmap(0, 4096 * 2 * N, PROT_READ | PROT_WRITE,
                      MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0);
     assert(tmp != MAP_FAILED);
-    ptr = (uint64_t *)tmp;
-    for (j = 0; j < 2; j++, ptr = (uint64_t *)(tmp + 4092)) {
-        uint64_t *ptr1 = ptr;
+    ptr = (uint32_t *)tmp;
+    for (j = 0; j < 2; j++, ptr = (uint32_t *)(tmp + 4094)) {
+        uint32_t *ptr1 = ptr;
         t1 = rdtsc();
         for (k = 0; k < 1ULL<<8; k++) {
-            for (ptr = ptr1, i = 0; i < N; i++, ptr += 4096 / 8)
+            for (ptr = ptr1, i = 0; i < N; i++, ptr += 4096 / 4)
                 *ptr += 1;
         }
         t2 = rdtsc();

mv ★★★★★
() автор топика
Ответ на: комментарий от tailgunner

Кстати, почему 1280?

Подбирал наиболее красивый результат, естественно =)

Ты не выходишь за границы TLB?

Да вообще за все границы выхожу. Если у кого кэш слишком жирный, смело увеличивайте в несколько раз, пока опять плохо не станет =)

mv ★★★★★
() автор топика
Ответ на: комментарий от mv

>> Ты не выходишь за границы TLB?

Да вообще за все границы выхожу.

Не, ну это нечестно :) Выход за границы всегда ведет к существенной разнице - задействуются тупо другие codepaths и что там у процессоров...

tailgunner ★★★★★
()
Ответ на: комментарий от mv

а выравнивание для чего тогда?!

Выравнивание где?

Постоянное выравнивание всего подряд на 2/4 и т д байт далеко не всегда полезно, а если мало кеша, то даже и вредно. Тут стоит понимать, что тормоза при обращении по невыровненому адресу происходят только тогда, когда считываемые данные находятся в разных кеш-линиях.

mv, может стоит посмотреть в сторону ядреных слабов? То есть вытащить их из ядра, спилить выступающие части...

AF ★★★
()
Ответ на: комментарий от mv

Колись. Что ты там пишешь такое, что нужен очень высокий КПД оптимизации? Видеокодек?

С какого момента за более высокую скорость надо платить хорошую цену. Стоит ли оно того? Обращать слишком много внимания на особенности работы кеша, выравнивания страниц памяти и т.д. не стоит. Завтра все поменяется и увеличение производительности сменится его уменьшением.

Кстати в моем примере очередь свободных объектов лучше заменить на стек. Будет проще и понятней.

pathfinder ★★★★
()
Ответ на: комментарий от AF

> mv, может стоит посмотреть в сторону ядреных слабов? То есть вытащить их из ядра, спилить выступающие части...

libumem это оно и есть

mukoh
()
Ответ на: комментарий от mv

use esi, Luke! ;)

kvt:~/tmp/11$ gcc a.c
a.c: In function `rdtsc':
a.c:10: error: unknown register name `edx' in `asm'
a.c:10: error: unknown register name `eax' in `asm'

А можно патч для спарка64?

ttnl ★★★★★
()
Ответ на: комментарий от ttnl

А можно патч для спарка64?

gettimeofday() вместо rdtsc(). И getpagesize(), если страница не 4кб.

mv ★★★★★
() автор топика
Ответ на: комментарий от AF

Постоянное выравнивание всего подряд на 2/4 и т д байт далеко не всегда полезно, а если мало кеша, то даже и вредно.

Если не i7, то всегда полезно. С i7, впрочем, у меня есть практическое подозрение, что он всё равно не всегда так круто оптимизирует доступ к невыровненным данным.

Тут стоит понимать, что тормоза при обращении по невыровненому адресу происходят только тогда, когда считываемые данные находятся в разных кеш-линиях.

Различных ситуаций, где тормоза вылазят, хватает.

mv ★★★★★
() автор топика
Ответ на: комментарий от pathfinder

Колись. Что ты там пишешь такое, что нужен очень высокий КПД оптимизации? Видеокодек?

ПО для более быстрого и точного наступления очередного финансового кризиса ;)

С какого момента за более высокую скорость надо платить хорошую цену. Стоит ли оно того? Обращать слишком много внимания на особенности работы кеша, выравнивания страниц памяти и т.д. не стоит.

Вот поэтому у всех us и даже ms, а у нас ns.

Завтра все поменяется и увеличение производительности сменится его уменьшением.

Завтра всё будет работать на том же железе, для которого проводилась оптимимзация. Если железа будет не хватать, а на новом будут тормоза, то под новое опять будет проведена оптимизация. Небесплатно, разумеется.

mv ★★★★★
() автор топика
Ответ на: комментарий от mv

А что тут должно тормозить?

Так вот и я о чем!

Тем не менее, чуть выше:

Тут стоит понимать, что тормоза при обращении по невыровненому адресу происходят только тогда, когда считываемые данные находятся в разных кеш-линиях.

Различных ситуаций, где тормоза вылазят, хватает.

AF ★★★
()
Ответ на: комментарий от mv

Я собственно, хотел узнать, при каких условиях i7 «не всегда так круто оптимизирует доступ к невыровненным данным»

AF ★★★
()
Ответ на: комментарий от AF

Не вопрос, только обьясни словами, что оно делает)

А что твой пример должен был продемонстрировать? Что 12 не кратно 4?

mv ★★★★★
() автор топика
Ответ на: комментарий от AF

Я собственно, хотел узнать, при каких условиях i7 «не всегда так круто оптимизирует доступ к невыровненным данным»

Исследований не проводил, но при работе с дофига разреженной памяти замечал, что i7 ведёт себя хуже, если адрес не выровненный.

mv ★★★★★
() автор топика
Ответ на: комментарий от mv

>А что твой пример должен был продемонстрировать? Что 12 не кратно 4?

Блиин! Я ж хотел для адреса 13 взять. Извини, что запутал.

А спросить хотел следующее - что может тормозить при доступе к невыровненным данным, если: а) данные находятся в одной линейке б) линейка находится в кеше

AF ★★★
()
Ответ на: комментарий от mv

>Исследований не проводил, но при работе с дофига разреженной памяти замечал, что i7 ведёт себя хуже, если адрес не выровненный.

Понятно. Но, имхо, врядли тут выравнивание виновато.

AF ★★★
()
Ответ на: комментарий от pathfinder

>Вот фантазия на тему. :)

Че-та неправильный какой-то C. Если с крестами, так можно сразу буст взять, там есть как раз такие пулы.

linuxfan
()
Ответ на: комментарий от mv

>ОДИН объект не должен лежать на границе страниц.

Можешь подвести под этот тезис разумное объяснение? А также разумно объяснить, почему один объект, размазанный по двум страницам, хуже, чем два объекта на разных страницах?

P. S. что-то я смотрю, занятия лиспом скатились к сношению битиков, которые скобочными средствами не делаются, вот и приходится возвращаться к истокам?

linuxfan
()
Ответ на: комментарий от AF

А спросить хотел следующее - что может тормозить при доступе к невыровненным данным, если: а) данные находятся в одной линейке б) линейка находится в кеше

Если проц не нехалем (i7 и соотв. зеоны), то тормозит только в путь.

mv ★★★★★
() автор топика
Ответ на: комментарий от tailgunner

>В одном месте сэкономил, в другом - потратил сэкономленное.

А мужики не в курсе, что существует TLB cache и даже инструкция для его сброса? Если бы все реально обстояло так плохо, как вы с mv думаете, современные приложения тормозили бы интенсивнее порядка эдак на два.

linuxfan
()
Ответ на: комментарий от linuxfan

> А мужики не в курсе, что существует TLB cache и даже инструкция для его сброса?

В usermode? Я лично не в курсе.

Если бы все реально обстояло так плохо, как вы с mv думаете

Я думаю, что, когда рабочее множество программы превышает размер кэша TLB, она начинает тормозить из-за того, что страниц в этом кэше нет. Если ты считаешь как-то по-другому - объясни, почему.

tailgunner ★★★★★
()
Ответ на: комментарий от linuxfan

Можешь подвести под этот тезис разумное объяснение? А также разумно объяснить, почему один объект, размазанный по двум страницам, хуже, чем два объекта на разных страницах?

Я, наверное, не правильно объяснил, что сразу два человека не так поняли. Но хотел сказать, что объект на одной странице лучше, чем этот же объект на двух страницах, т.е. лежит на их границе. Про два объекта на разных страницах речь не шла.

Объясняется легко: вместо одного tlb lookup надо два делать.

mv ★★★★★
() автор топика
Ответ на: комментарий от linuxfan

Если бы все реально обстояло так плохо, как вы с mv думаете, современные приложения тормозили бы интенсивнее порядка эдак на два.

Они и так тормозят. Вы просто не видели, как работают быстрые, вручную вылизанные программы =)

mv ★★★★★
() автор топика
Ответ на: комментарий от mv

> Но хотел сказать, что объект на одной странице лучше, чем этот же объект на двух страницах, т.е. лежит на их границе

Я так и понял. Но цифры от твоего теста кажутся сильно завышенными.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Я думаю, что, когда рабочее множество программы превышает размер кэша TLB, она начинает тормозить из-за того, что страниц в этом кэше нет. Если ты считаешь как-то по-другому - объясни, почему.

Факт, что замусоривание кэша TLB ведёт почти к такому же просаживанию скорости, как замусоривание обычного кэша.

mv ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.