Здравствуйте, remark, Вы писали:
R>В-четвёртых, при замесе двух потоков эффективная длина конвеера получается меньше, т.к. сбрасывать из него надо только часть команд, которые относятся к потоку, который вызвал сброс. Что в общем-то хорошо.
С другой стороны, из-за этих всех эффектов мы потеряем в однопоточной производительности.
Здравствуйте, Cyberax, Вы писали:
R>>В-четвёртых, при замесе двух потоков эффективная длина конвеера получается меньше, т.к. сбрасывать из него надо только часть команд, которые относятся к потоку, который вызвал сброс. Что в общем-то хорошо. C>С другой стороны, из-за этих всех эффектов мы потеряем в однопоточной производительности.
C>Поэтому я и сомневаюсь, что оно так работает.
Ну, с другой стороны — ты представляешь, насколько дорого поток переключить при таком глубоком конвейре? Это примерно то же самое, что обеспечить точную обработку исключения. Вторая проблема — тебе надо понять, когда его переключать, а это не так просто. Единичный паромах в кэш данных не может являться поводом для переключения — с ним легко справится суперскаляр. Более того — конвейер глубокий, и в случае промаха в кэш данных ты слишком поздно поймешь, что пора переключать поток, и у тебя будет "пузырь". Вариант без "пузыря" — это уметь подавать в конвейер команды с другого потока, пока в конвейере все еще есть команды первого потока — не сбрасывая конвейер. Делается это просто — достаточно сделать разные физические адреса регистров двух потоков в общем регистровом файле.
Здравствуйте, Gaperton, Вы писали:
G>Ну, с другой стороны — ты представляешь, насколько дорого поток переключить при таком глубоком конвейре?
А он не глубокий. Точной информации нет, но он в 14 команд всего в Core2 и вряд ли сильно изменится в Nehalem. Это не P4 с его конвейером в 30 команд.
G>Это примерно то же самое, что обеспечить точную обработку исключения. Вторая проблема — тебе надо понять, когда его переключать, а это не так просто. Единичный паромах в кэш данных не может являться поводом для переключения — с ним легко справится суперскаляр.
При branch misprediction — не справится. При обычном промахе — тоже, скорее всего, из-за зависимостей по данным.
А ещё есть lookup'ы в таблице страниц при промахах в TLB и прочие совсем уж жуткие вещи.
G>Более того — конвейер глубокий, и в случае промаха в кэш данных ты слишком поздно поймешь, что пора переключать поток, и у тебя будет "пузырь". Вариант без "пузыря" — это уметь подавать в конвейер команды с другого потока, пока в конвейере все еще есть команды первого потока — не сбрасывая конвейер. Делается это просто — достаточно сделать разные физические адреса регистров двух потоков в общем регистровом файле.
Это уже как-то более похоже на правду звучит — выполнение команд другого потока не всё время, а только в случае образования "пузырей". Это будет однозначно эффективнее моего изначального предположения. Но потребует больше ресурсов, так как нужно параллельно уметь выбирать и декодировать команды двух потоков.
Здравствуйте, Cyberax, Вы писали:
G>>Более того — конвейер глубокий, и в случае промаха в кэш данных ты слишком поздно поймешь, что пора переключать поток, и у тебя будет "пузырь". Вариант без "пузыря" — это уметь подавать в конвейер команды с другого потока, пока в конвейере все еще есть команды первого потока — не сбрасывая конвейер. Делается это просто — достаточно сделать разные физические адреса регистров двух потоков в общем регистровом файле. C>Это уже как-то более похоже на правду звучит — выполнение команд другого потока не всё время, а только в случае образования "пузырей". Это будет однозначно эффективнее моего изначального предположения. Но потребует больше ресурсов, так как нужно параллельно уметь выбирать и декодировать команды двух потоков.
Смори, как там _может_ быть. АЛУ все SSE-шные, шириной 128 бит, так? При этом, fuse может быть устроен так, что пытается клеить обычные 64-х битные команды в пары — чтобы как следует нагрузить это АЛУ — а то его половина будет простаивать. При этом, одного потока, чтобы сделать такой Fuse, будет маловато — и в Core 2 так не делаетася. А вот если у нас будут готовые к выполнению инструкции с двух потоков, независимых по регистрам?
При этом, читать команды одновременно с двух потоков не надо — достаточно применить при выборке команд револьверную систему.
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, remark, Вы писали:
R>>В-четвёртых, при замесе двух потоков эффективная длина конвеера получается меньше, т.к. сбрасывать из него надо только часть команд, которые относятся к потоку, который вызвал сброс. Что в общем-то хорошо.
C>С другой стороны, из-за этих всех эффектов мы потеряем в однопоточной производительности.
А почему?
Моё наивное видение такое, что если второго потока нет, то всё будет отдано под первый, и он будет выполняться так как будто HT нет.
Здравствуйте, remark, Вы писали:
R>>>В-четвёртых, при замесе двух потоков эффективная длина конвеера получается меньше, т.к. сбрасывать из него надо только часть команд, которые относятся к потоку, который вызвал сброс. Что в общем-то хорошо.
C>>С другой стороны, из-за этих всех эффектов мы потеряем в однопоточной производительности.
R>А почему? R>Моё наивное видение такое, что если второго потока нет, то всё будет отдано под первый, и он будет выполняться так как будто HT нет.
Скажу больше. А если он, второй поток — есть, то его выполнение один хрен замедлит выполнение первого потока, как их не переключай, хоть раз в 15 мсек. А вот при замесе — одновременное выполнение будет эффективнее.
R>Не понятно, за счёт чего прирост производительности — из-за L3 кэша, или HT, или ещё чего-то. Но если за счёт HT, то 40% — это очень и очень хорошо. Предыдущий HT на Pentium4 давал теоретический максимум — +30%, и +30% достигали очень немногие приложения, некоторые получали -5%.
у меня HT на P4 давал прирост близкий к 100% (криптография).