|
|
  |
IBQ stalls на С55x, или как их избежать |
|
|
|
Mar 19 2007, 16:50
|
Частый гость
 
Группа: Свой
Сообщений: 121
Регистрация: 23-09-05
Из: Москва
Пользователь №: 8 874

|
О том как работает fetch конвейер в мануалах TI написано скупо и поверхностно. Буфер IB наполняется со скоростью 4 байта, а опустошается 1-6 байт. Смотрю в Pipeline Stall Analyzer по ходу программы IB начинает опустошаться и возникает IBQ stall причем никакими страшными 5 и 6 байтными командами и вызовами и циклами не пахнет. Отсюда возникают вопросы: При каких условиях перестает наполняться очередь и при каких вознобновляется. Вот для примера кусочек кода: Код _func NOP_16 || NOP NOP_16 || NOP_16 NOP_16 || NOP NOP_16 || NOP NOP_16 || NOP NOP_16 || NOP_16 NOP_16 NOP_16 || NOP NOP_16 NOP_16 || NOP NOP_16 || NOP_16 NOP_16 || NOP NOP_16 || NOP_16 NOP_16 || NOP_16 NOP_16 || NOP_16 RET В процессе выполнения последние 2 инструкции перед RET оказываются отсеченными IBQ stall. Почему? Никаких видимых препятствий для наполнения буфера нет.
|
|
|
|
|
Mar 20 2007, 14:31
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(Warlord @ Mar 20 2007, 10:11)  Жизнь совпадает с симулятором - 32 такта, включая CALL(5) и RET(11), 15 инструкций, 1 stall Как предположение - RET делает что-то с IBQ когда находится в AD или AC1 конвейера, что и вгоняет его в stall. Второе подозрительное - в описании фазы D сказано, что она читает 6 байт из IBQ. А не "up to 6". Точно также как и сказано, что IBQ читает по 32 бита, а отправляет в декодер пакетами по 48. Так что остается только гадать, как это там внутри происходит.
|
|
|
|
|
Mar 20 2007, 16:17
|
Частый гость
 
Группа: Свой
Сообщений: 121
Регистрация: 23-09-05
Из: Москва
Пользователь №: 8 874

|
Stall происходит потому что по непонятным причинам опустошается IB и нечего подавать на фазу D. Это случается еще до попадания в фазу D инструкции RET.  На скриншоте два stall-а, первый из которых - непонятный(фаза AC2), а второй - это происходит принудительная очистка конвеера перед возвратом из функции. Цитата в описании фазы D сказано, что она читает 6 байт из IBQ. А не "up to 6". Точно также как и сказано, что IBQ читает по 32 бита, а отправляет в декодер пакетами по 48 Одно совпадает точно - IB наполняется с постоянной скоростью 4 байта или не наполняется вовсе. Если команды - одиночные NOP-ы, то видно что IB опустошается не 6 байтами, а как и следовало ожидать по 1 байту. Мануал магически говорит: Цитата Instructions stored in the IBQ are dispatched to the execution pipeline in 48-bit packets and consumed by the decode (D) phase of the pipeline at a rate that depends on the length of the instruction being decoded. Вообще говоря, работа плагина как-то не вяжется с описанием работы конвеера, так та пачка(по сути преддекодированая инструкция), что д.поступить в D куда-то из IBQ пропадает, и IBQ уменьшается ровно на размер этой пачки. Иногда размер IBQ становится равным 64/64, хотя видно, что очередь пуста... Хоть в TI support пиши, чтоб объяснили...
|
|
|
|
|
Mar 20 2007, 17:41
|
Частый гость
 
Группа: Свой
Сообщений: 121
Регистрация: 23-09-05
Из: Москва
Пользователь №: 8 874

|
Опечатался со stall-ом в AC2. Рис.1 буфер пуст, хотя показывает 64/64 от балды что ли??  Потом возникает IBQ-stall рис.2 и в конвеер вваливается пустышка рис.3  Так вот непонятный это первый рисунок, почему буфер пустой, почему его размер 64/64 и что мешает ему заполняться... Что касается RET то тут все правильно и ясно, конфликтов нет, адрес возврата берется из регистра RETA.
|
|
|
|
|
Mar 21 2007, 10:27
|
Частый гость
 
Группа: Свой
Сообщений: 121
Регистрация: 23-09-05
Из: Москва
Пользователь №: 8 874

|
Запустил CCS 3.1 где плаг версии 3.0. Тут несколько другая картина Рис.1 Код NOP_16 || NOP <- адрес 0x12b9a находится в предекоде. NOP_16 || NOP_16 <-3 байта из 4х находятся в буфере NOP_16 || NOP_16 NOP_16 || NOP_16 RET  В преддекоде сидит NOP_16 || NOP(в буфере она не отображается). В буфере 3 байта следующей 4 байтовой инструкции NOP_16 || NOP_16 Рис.2 Код NOP_16 || NOP <- уходит в execute конвееер в фазу D NOP_16 || NOP_16 <-адрес 0x12b9d уходит в предекод. NOP_16 || NOP_16 <- начиная с этого адреса в буфере лежит 64 байта NOP_16 || NOP_16 RET  Проц считывает в буфер 1+64 байта (вместо положенных 4) и 3+1 уходят на преддекодирование. Видно что в буфере остается 64 байта. Рис.3 Буфер полностью очищается и в него поступают почему-то 3 байта!! а на преддекодирование идет пустышка, и возникает stall. Код NOP_16 || NOP NOP_16 || NOP_16 <- уходит в execute конвееер в фазу D NOP_16 || NOP_16 <- снова адрес 0x12b9d(хотя уже считано)в буфер ложатся 3 байта, возникает stall NOP_16 || NOP_16 RET  Рис. 4 В очередь дочитывается след.4 байта, 3+1 (NOP_16 || NOP_16) уходят на предекодирование и далее все нормально. Код NOP_16 || NOP NOP_16 || NOP_16 NOP_16 || NOP_16 <- адрес 0x12ba1 находится в предекоде, в фазу D пустышка NOP_16 || NOP_16 RET  Если не трудно, просимулите этот пример, может чего прояснится..
|
|
|
|
|
Mar 21 2007, 13:32
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Просимулил... Не прояснилось. Вот код полностью: Код .cpl_off .c54cm_off .arms_off .global start
.sect ".vectors" vecs: .ivec begin,USE_RETA .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .ivec iret1 .text start: bset intm mov #vecs>>8,mmap(@IVPD) mov #vecs>>8,mmap(@IVPH)
rpt #5 nop reset halt: b halt
begin:; nop ; !!!!!!!!!!! call test b begin
test: NOP_16 || NOP NOP_16 || NOP_16 NOP_16 || NOP NOP_16 || NOP NOP_16 || NOP NOP_16 || NOP_16 NOP_16 NOP_16 || NOP NOP_16 NOP_16 || NOP NOP_16 || NOP_16 NOP_16 || NOP NOP_16 || NOP_16 NOP_16 || NOP_16 NOP_16 || NOP_16 RET
iret1: reti Вся непонятка в том, что сталл зависит от NOP'а перед CALL. Если его нет - stall. Если он есть - сталла не стало. Из идей, почему так - есть предположение, что IBQ имеет какое-то кривое состояние, зависящее от состояния внутренних указателей, или еще х.з. чего-то там в нем, которое показывается как 64/64, и требует немедленной очистки IBQ, приводящей к этому stall'у. При этом четко видно, что в состоянии 64/64 там уже напрефетчено все вплоть до reti, т.е. на самом деле далеко не 64, а значительно меньше. Но вот что это за состояние, и как в него не попадать, я думаю может сказать только аффтар этого чудо-префетчера, а до меня суть не доходит (несмотря на то, что сам не так давно сделал очень похожий блок префетчера для своего микропроцессора)
|
|
|
|
|
Mar 21 2007, 15:32
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(Warlord @ Mar 21 2007, 14:57)  а когда на преддекод поступает команда RET, то буфер забивается 64 байтами (1байт начитается сразу после call test, так называемый speculative fetch). Тут все правильно, так и д.б. Да не должно так быть. Откуда там взяться 64 байтам-то? Неоткуда. Не было там столько тактов между входом RET в decode и началом префетча с адреса возврата, чтобы набить полный буфер. Это именно какое-то неадекватное состояние префетчера. И вообще, он как-то странно работает. Если исполнять одни NOPы, то он не префетчит больше 16 байт, хотя было бы ожидаемо, что набъет весь буфер до упора. Дела тёмные какие-то.
|
|
|
|
|
Mar 21 2007, 16:37
|
Частый гость
 
Группа: Свой
Сообщений: 121
Регистрация: 23-09-05
Из: Москва
Пользователь №: 8 874

|
Согласен, 64 байта в буфере - это косяк, тут без специалиста TI не разобраться.. Цитата IBQ fetch advance can be between 0 and 24 bytes. т.е. если одни NOP-ы идут, то следовало ожидать, что наполненность буфера будет колебаться от 20 до 24, наполняясь каждые 4 такта.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|