Да объяснить то не слишком сложно:
1. В Iterate() везде сделать чтобы если .my_n>1, то обращения к mm, vC, nmods были бы не к глобальным исходным массивам, а к локальным копиям. Вероятно проще все указатели убрать в регистры и правильно их инициализировать в начале.
2. В конце Iterate() перед меткой .next надо проверить .my_n и если больше 1 (или RCX==2 прямо перед call), то вместо рекурсивного вызова Iterate() сделать кучу других действий:
2.1. Увеличить счётчик запущенных потоков.
2.2. Запустить новый поток, передав ему его номер, в котором запустить новую функцию скажем IterateTh(). Где-то сохранить handle потока для п.2.3.
2.2.1. В этой функции скопировать локально нулевой и первый элементы mm (размером 172*128), остаток mm и весь vC и весь nmods обнулить (разумеется локальные копии).
2.2.2. Вызвать Iterate() с локальными mm, vC, nmods.
2.2.3. Атомарно (например через критическую секцию) добавить локальные vC и nmods к глобальным. Как обработать mm пока не знаю, надо вспоминать что это и зачем.
2.2.4. Выйти.
2.3. Чуть ниже метки .next, после jnz .cycle, ждать завершения всех запущенных потоков (функцией WinAPI
WaitForMultipleObjects).
3. Из Iterate() убрать код показа прогресса в начале. В многопоточной среде вызовы WinAPI wsprintf и WriteFile глючат. Сделать нормальный прогресс можно, но это ещё столько же изменений кода как всё выше. Либо сделать очень грубый показ прогресса, только в одном потоке, с наименьшим номером (он дольше всех работает), это несложно.
Вот как-то так. Кажется это самый простой способ. И мне он не очень нравится.
Не факт что после этого будет работать, что-то сомневаюсь что можно mm сделать локальным, надо разбираться зачем он.
И не факт что ничего не забыл.
Разумеется по хорошему ещё надо добавить обработку разных аварийных ситуаций (например поток не запустился или не завершился).
Да, в таком варианте запустится много потоков, сколько может быть однократных загрязнений, но обычно это сильно больше 12, так что потоки будут конкурировать за время CPU, с этим ОС более-менее нормально справляется, ограничить количество потоков тут непросто (можно перед запуском очередного потока ждать пока количество запущенных не снизится до N-1 и только тогда запускать очередной, для этого в п.2.2.4 перед выходом атомарно уменьшать счётчик запущенных потоков и убрать его handle из списка из п.2.2).
Я
очень сильно сомневаюсь что всё это (или лучше) может сделать ИИ.
-- добавлено через 23 минуты --Для проверки "понимания" ИИ кода программы задайте ему простой вопрос: какие массивы меняются в Iterate(). Я прямо по коду вижу что mm, vC, nmods. Если он ответит меньше, то это facepalm - потому что это базовое понятие, что придётся делать локальным и потом как-то объединять от разных потоков в глобальные.
-- добавлено через 6 минут --Кстати при неаккуратной реализации, например не дублировать массивы локально, а атомарно менять сразу глобальные, как вполне может предложить ИИ, работать многопоточно будет
медленнее! Потому что массивы меняются очень часто и всё время будут занимать вызовы WinAPI для атомарного изменения.