Я реализовал PARLANSE, язык под MS Windows, который использует стеки кактусов для реализации параллельные программы. Фрагменты стека выделяются для каждой функции и имеют просто размер, подходящий для обработки локальных переменных, временных буферов выражений и вызовов библиотек (включая пространство стека для библиотечных подпрограмм, в которых они работают). ). Такие кадры стека на практике могут иметь размер всего 32 байта и часто так и есть.
Все это прекрасно работает, если только код не делает глупостей и не вызывает аппаратную ловушку... в этот момент Windows, кажется, настаивает на отправке всего контекста машины x86 "в стек". Это около 500+ байт, если включить FP/MMX/и т.д. регистрирует, что он и делает. Естественно, 500-байтовая загрузка в 32-байтовый стек разрушает то, чего не должна делать. (Аппаратное обеспечение помещает в ловушку несколько слов, но не весь контекст).
[EDIT 27/11/2012: см. это для измеренных подробностей о нелепом количестве стека, которое Windows фактически выталкивает< /а>]
Могу ли я заставить Windows хранить блок контекста исключения в другом месте (например, в месте, определенном для потока)? Тогда программное обеспечение могло бы принять исключение в потоке и обработать его, не переполняя мои небольшие кадры стека.
Я не думаю, что это возможно, но я решил попросить гораздо большую аудиторию. Есть ли стандартный вызов/интерфейс ОС, из-за которого это может произойти?
Это было бы тривиально сделать в ОС, если бы я мог убедить MS разрешить моему процессу необязательно определять место хранения контекста, «contextp», которое инициализируется для включения текущего устаревшего поведения по умолчанию. Затем замените векторный код прерывания/ловушки:
hardwareint: push context
mov contextp, esp
... с участием ...
hardwareint: mov <somereg> contextp
test <somereg>
jnz $2
push context
mov contextp, esp
jmp $1
$2: store context @ somereg
$1: equ *
с очевидными изменениями, необходимыми для сохранения somereg и т. д.
[Что я сейчас делаю: проверяю сгенерированный код для каждой функции. Если есть шанс сгенерировать ловушку (например, деление на ноль) или мы проводим отладку (возможно, неправильное отключение указателя и т. д.), добавьте достаточно места в кадр стека для контекста FP. Кадры стека теперь имеют размер ~~ 500-1000 байт, программы не могут выполнять рекурсию так далеко, что иногда является реальной проблемой для приложений, которые мы пишем. Итак, у нас есть работоспособное решение, но оно усложняет отладку]
РЕДАКТИРОВАТЬ 25 августа: мне удалось передать эту историю внутреннему инженеру Microsoft, у которого, по-видимому, есть полномочия выяснить, кого в MS это может волновать. Возможно, есть слабая надежда на решение.
РЕДАКТИРОВАТЬ 14 сентября: MS Kernal Group Architect слышал эту историю и сочувствует. Он сказал, что MS рассмотрит решение (подобное предложенному), но вряд ли оно будет в пакете обновлений. Возможно, придется ждать следующей версии Windows. (Вздох... Я мог бы состариться...)
РЕДАКТИРОВАТЬ: 13 сентября 2010 г. (год спустя). Никаких действий со стороны Microsoft. Мой последний кошмар: ловушка, запускающая 32-битный процесс в Windows X64, поместит весь контекст X64 в стек до того, как обработчик прерывания подделает 32-битный контекст? Это было бы еще больше (вдвое больше целочисленных регистров, в два раза больше, в два раза больше регистров SSE (?))?
РЕДАКТИРОВАТЬ: 25 февраля 2012 г.: (прошло 1,5 года...) Никакой реакции со стороны Microsoft. Думаю, им просто наплевать на мой вид параллелизма. Я думаю, что это медвежья услуга сообществу; «модель большого стека», используемая MS при нормальных обстоятельствах, ограничивает количество параллельных вычислений, которые можно выполнять в любой момент, потребляя огромное количество виртуальных машин. Модель PARLANSE позволит иметь приложение с миллионом живых «зёрен» в различных состояниях выполнения/ожидания; это действительно происходит в некоторых наших приложениях, где граф из 100 миллионов узлов обрабатывается «параллельно». Схема PARLANSE может сделать это с примерно 1 ГБ ОЗУ, что вполне управляемо. Если бы вы попробовали это с «большими стеками» MS 1Mb, вам потребовалось бы 10 ^ 12 байт виртуальной машины только для пространства стека, и я почти уверен, что Windows не позволит вам управлять миллионом потоков.
РЕДАКТИРОВАТЬ: 29 апреля 2014 г.: (прошло 4 года). Думаю, MS просто не читает SO. Я проделал достаточно инженерных работ на PARLANSE, поэтому мы платим только за большие кадры стека во время отладки или когда выполняются операции FP, поэтому мы удалось найти очень практичные способы жить с этим. MS продолжает разочаровывать; количество вещей, помещаемых в стек различными версиями Windows, кажется, значительно и вопиюще различается, помимо необходимости только аппаратного контекста. Есть некоторый намек на то, что часть этой изменчивости вызвана тем, что продукты, отличные от MS, застревают (например, антивирус), засовывая свой нос в цепочку обработки исключений; почему они не могут сделать это из-за пределов моего адресного пространства? В любом случае, мы справляемся со всем этим, просто добавляя большой коэффициент погрешности для ловушек FP / отладки и ожидая неизбежной системы MS в поле, которая превышает это количество.