Допустим разрядность элемента массива равна разрядности слова банка, каждый банк имеет отдельную шину адреса и данных. Если мы поделим память на 4 банка и конкретный банк будут выбирать 2 младших бита адреса, то нет никаких проблем прочитать 4 подряд идущих элемента, начиная с любого банка. Если шаг между элементами будет кратен 2, к примеру в массиве лежат двумерные координаты, а обновить нам требуется только X, половина банков у нас будет простаивать, а другая трудиться в два раза дольше. Если в массиве лежат трёхмерные координаты, то обновить X можно без проблем задействуя все 4 банка, да и вообще проблем не будет со структурами из нечётного числа слов. А вот когда структура станет кратна 4м словам, то при обновлении X трудиться придётся одному банку, пока другие будут простаивать.
Решений здесь существует несколько:
1) Растащить поля структуры по отдельным массивам, в структуру поместить адреса этих массивов, чтобы по индексу можно было собрать нужную структуру из разных массивов.
2) Дополнить структуру до нечётного числа слов, что несколько затратно по памяти для мелких структур.
3) Самый интересный вариант - сделать больше банков, сохранив в целях совместимости количество шин.
Для последнего варианта можно поделить каждый банк на 5 более мелких(всего 20 банков), и добавить 5 ортогональных шин. Если младший бит шага между элементами нечётный, запросы идут по 4м шинам как обычно, а если чётный, значит их нужно перенаправить на ортогональные шины. Здесь правда возникает проблема, если шаг будет кратен и тому и другому, к примеру 10 или 20. В этом случае придётся вернуться ко 2 варианту, но затраты памяти здесь уже будут 10% или 5%, а не 50% как в случае структур из двух слов. Можно рассмотреть и схемы разбиения 8x9 или 16x17, но для них всех нужен быстрый алгоритм вычисления остатка при делении на числа вида 2^n+1, у кого какие соображения по этому поводу? Скорее всего это будет что-то типа признака делимости на 11 для десятичной системы, но насколько сложная схема получится для железа?
Есть еще вариант вычислить от адреса CRC, после чего делить его на номер банка и номер ячейки в нём, здесь конфликты будут возникать для любого шага, но в теории они они должны быть равномерны по всем банкам и очередь может помочь с ними справиться. Опять же вопрос насколько сложно это будет для железа?
PS: В общем мысль про CRC пришла к выводу, что имеея 2^n банков достаточно разбить адрес на группы по n бит после чего их все проксорить. Таким образом можно будет параллельно обращаться к элементам с любым шагом и в среднем нагрузка на банки будет равномерной. Есть правда минус в том, что для каждого банка нужна очередь запросов, и при конфликтах время получения всех данных будет удлиняться. Плюс метода в том, что при изменении количества банков нужно только скорректировать количество параллельно обрабатываемых элементов, а переделывать размещение данных не потребуется.




Ответить с цитированием