Как стать автором
Обновить

Комментарии 15

у старших ядер (big) размер кэш-линий составляет 128 байт, а младших (LITTLE) — 64

Вот так поворот! Можно уточнить — речь идет о размере кеш линий инструкций или инструкций и данных?


PS: Спасибо за статью

речь идет про кэш инструкций.

Я понимаю, что глупо общаться с переводом, но всё же хочу прояснить несколько деталей.
У ARMv8 нет инструкции, которая получает размер кеша. Вводить отдельную инструкцию для такой операции было бы глупо. Вместо этого есть регистры которые описывают структуру кеша. Они описаны в ARM Architecture Reference Manual ARMv8 в разделе D3.4.2 Cache identification. И первым делом там сказано вот что:

The ARMv8 cache identification registers describe the implemented caches that are affected by cache maintenance
instructions executed on the PE


PE — это Processing Element, т.е. просто процессор. Короче, регистры описывают структуру кеша на конкретном процессоре. Что, в принципе абсолютно логично.
То что шедуллер ОС может перекидывать код с одного ядра на другое, это не проблема архитектуры процессора. Пользовательский код должен учитывать это и например просить шедуллер не делать так.

Поэтому, я сильно не согласен с вот этой фразой:
Хуже того, даже набор инструкций ARM не готов к этому.


Это просто ошибка в имплементации libgcc.
Пользовательский код должен учитывать это и например просить шедуллер не делать так.

Такое возможно сделать в юзерспейсе?

Ага. Системный вызов sched_setaffinity() позволит прибить поток к конкретному ядру.
>> set_affinity()

ОС может работать в режиме Cluster Migration или CPU Migration, когда пара ядер (большое и маленькое) видны как одно.
Старые Exynos типа 5410 могут работать лишь в первом режиме.
Аффинити тут не поможет.

Собственно это и была фишка big.LITTLE. Например Apple A10 работает так.
Более того — переключение может происходить без участия ОС, аппаратно.

Правильней таки получать минимальный размер строчки кеша откуда нибудь из ОС.

что-то типа?


foreach core
  set_affinity
  get_cache_line_size
Ну если мы хотим узнать параметры кешей на каждом ядре — то да, именно так.

Да, чтобы выяснить минимальный размер кэш линии, как было сказано в статье.
А еще эти ядра могуть уходить в offline.
Не знаю будет ли в этом случае работать set_affinity.

Мне кажется эта тема уже поднималась на Хабре.
То есть как бы сам факт такой необычной реализации уже не является новым, интереснее другое — как все-таки с этим жить? Не будет ли многопоточный код ломаться непредвиденно? И так на ARM более мягкие правила reordering'а, чем на x86, и плюс еще дополнительная нестабильность.
Никто лёгкой жизни и не обещал
"… While those CPU cores are functionally equivalent, they may differ in implementation details such as cache topology. "
Судя по изменениям, баг просто сделали более сложным в воспроизведении, но не избавились полностью. И даже сами признают, что может произойти, просто гораздо менее вероятно.
Вспомнил про эту историю, поглядел на код, почитал документацию…
В исправлении используют значение размера кэш-линии из регистра CTR_EL0, где лежит, собственно, размер самой короткой кэш-линии кэша инструкций. Более того, в документации ARM есть пример инвалидации кэша инструкций и для размера кэш-линии как раз берётся то значение. Так что, должно работать исправно.
Поправка (подразумевалось при написании комментария выше, но было упущено): там лежит не сам размер, а двоичный логарифм размера в словах, которые, соответственно, 4 байта, отсюда и берётся затем побитовый сдвиг 4 влево на эту величину.
А, нет, пардон, в документации сказано, что в CTR_EL0 лежит:
Log2 of the number of words in the smallest cache line of all the instruction caches that the processor controls

Всё, понял. В одном чипе два процессора. И между их ядрами спокойно могут мигрировать.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории