LINUX.ORG.RU

Головоломка с кешем инструкций L1


0

1

Процессоров все больше, ядра все круче, параллельность выше..

Как указывать кеш инструкций L1 для компиляции в gcc, если процессоров два, и к тому же они еще и делятся на два виртуальных ядра гипертрейдингом..

С кешем L2 все понятно 2 процессора на 2 виртуальных ядра, то указанное значение делим на 4.

Общий кеш L2 процессора в примере 1024К. При значении 256К на ядро получаем наиболее высокие показатели обмена:

#cat /sys/devices/system/cpu/cpu0/cache/index2/size
512 K

sysbench --test=memory --memory-block-size=128K --max-time=30 run
80859.12 MB transferred (2695.28 MB/sec)

sysbench --test=memory --memory-block-size=256K --max-time=30 run
90526.25 MB transferred (3017.51 MB/sec)

sysbench --test=memory --memory-block-size=512K --max-time=30 run
81594.00 MB transferred (2719.76 MB/sec)

sysbench --test=memory --memory-block-size=1024K --max-time=30 run
46810.00 MB transferred (1560.29 MB/sec)

По идее L1 у каждого процессора свой. Но как быть с виртуальностью ядер каждого процессора делить меж ними кеш пополам или нет????

Заранее благодарен.

Но как быть с виртуальностью ядер каждого процессора делить меж ними кеш пополам или нет????

Нет.

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

Спасибо, но дело в том, что уверености в этом нету... Можно ли это как-нибудь подтвердить экспериментально? Прошуршал разные даташиты до корки, руководство по gcc. Искомых ответов не нашел.

CPU дает возможность запускать 4 процесса параллельно, которые распределятся по 4-ом виртуальным ядрам. Если указать 32к на ядро, то разве не получится ли ситуация, когда на каждом процессоре два конкурирующих процесса на виртуальных ядрах будут вымывать кеш по очереди полностью?

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

Если указать 32к на ядро,

Это лишь хинт по оптимизациям компилятору, к хардварной логике работы кеша это отношения не имеет.

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

Примерно также, как и на одном ядре.

madcore ★★★★★ ()

т.е. если у меня 1 cpu на 2 ядра, без НТ и cpuinfo говорит, что L2 (например) 2048К, то в gcc надо указывать 1024К?

и где про это почитать?

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

Похоже, что так.. Зря я голову ломал.

Попробовал на однопроцессорном с двумя виртуальными ядрами запустить два процесса (одинаковые и разные) и замерить результаты с разными вариантами компиляции. Толи очень мешает кеш L2 отловить разницу, толи результаты действительно одинаковы в пределах погрешностей.

Спасибо.

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

Замерь с помощью sysbench:

sysbench --test=memory --memory-block-size=сюда_подставляем_размер_кеша_на_ядроK --max-time=30 run

Результат с лучшими показателями и будет желательным значением. И хотя кеш L2 обычно общий на все процессоры и распределяется между процессорами в зависимости от частоты их обращений к обычной памяти, экспериментально получается, что желательно его равномерно разделять между ядрами. По крайней мере на интелах. Как в амд не знаю - не на чем проверить.

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

т.е. если у меня 1 cpu на 2 ядра, без НТ и cpuinfo говорит, что L2 (например) 2048К, то в gcc надо указывать 1024К?

Нет.
В теории, возможны варианты интересные, но устанешь искать да еще практически применять.

и где про это почитать?

В спеках конкретного проца.
На случай, если я слишком категоричен.

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

Попробовал на однопроцессорном с двумя виртуальными ядрами запустить два процесса

Если ты про гхипертрединг - то виртуализируются только вычислительные ресурсы проца, узкое «очко» - оно как было, так и осталось на одно ядро.

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

яничегонепонял.жпг

~ #  cat /proc/cpuinfo | grep "cache size"
cache size	: 2048 KB
cache size	: 2048 KB
~ # sysbench --test=memory --memory-block-size=2048K --max-time=30 run | grep "MB/sec"
66156.00 MB transferred (2205.19 MB/sec)
~ # sysbench --test=memory --memory-block-size=1792K --max-time=30 run | grep "MB/sec"
87542.00 MB transferred (2918.01 MB/sec)
~ # sysbench --test=memory --memory-block-size=1536K --max-time=30 run | grep "MB/sec"
102400.50 MB transferred (3425.64 MB/sec)
~ # sysbench --test=memory --memory-block-size=1280K --max-time=30 run | grep "MB/sec"
102400.00 MB transferred (4553.84 MB/sec)
~ # sysbench --test=memory --memory-block-size=1024K --max-time=30 run | grep "MB/sec"
102400.00 MB transferred (4923.30 MB/sec)
~ # sysbench --test=memory --memory-block-size=768K --max-time=30 run | grep "MB/sec"
102400.50 MB transferred (5254.89 MB/sec)
~ # sysbench --test=memory --memory-block-size=512K --max-time=30 run | grep "MB/sec"
102400.00 MB transferred (5554.41 MB/sec)
~ # sysbench --test=memory --memory-block-size=256K --max-time=30 run | grep "MB/sec"
102400.00 MB transferred (5219.42 MB/sec)

почему 512?

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

Нет.
В теории, возможны варианты интересные, но устанешь искать да еще практически применять.

понятно

seed_stil ★★ ()
Ответ на: яничегонепонял.жпг от seed_stil
~ # sysbench --num-threads=2 --test=memory --memory-block-size=1792K --max-time=30 run | grep "MB/sec"
102401.25 MB transferred (4693.60 MB/sec)
~ # sysbench --num-threads=2 --test=memory --memory-block-size=1280K --max-time=30 run | grep "MB/sec"
102400.00 MB transferred (5699.83 MB/sec)
~ # sysbench --num-threads=2 --test=memory --memory-block-size=1024K --max-time=30 run | grep "MB/sec"
102400.00 MB transferred (6116.81 MB/sec)
~ # sysbench --num-threads=2 --test=memory --memory-block-size=768K --max-time=30 run | grep "MB/sec"
102400.50 MB transferred (9571.63 MB/sec)
~ # sysbench --num-threads=2 --test=memory --memory-block-size=512K --max-time=30 run | grep "MB/sec"
102400.00 MB transferred (9041.24 MB/sec)
~ # sysbench --num-threads=2 --test=memory --memory-block-size=256K --max-time=30 run | grep "MB/sec"
102400.00 MB transferred (8413.01 MB/sec)
seed_stil ★★ ()
Ответ на: комментарий от ckotinko

кэш не «делится между ядрами». кэш бывает N-ассоциативным, с линейкой длины M и количеством линеек в банке L. для начала. запись из кэша в оперативку всегда медленнее чтения. в разы. настолько, что чтение+запись нынче=запись по времени.

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

Я не настолько тупой и в курсе этих мелочей. Вместо этого предложил бы лучше рабочий способ как протестировать, чтобы избежать влияния одного кеша на другой. А «афтар читай уже» забери себе.

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

Да, два ядра, два потока общих, на сайте интела тоже утверждают про это.

Попробуй повторить тест с 256к, 512к, 1024к и 2048к после чистой загрузки системы.

glibych ★★ ()

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

или ты вебдизайнер?

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