2010-07-21 1 views
2

Я реализую эту маленькую игру идею, которая (как-то?), Похожую на игру Конвея жизнь:Может ли многопоточность повлиять на клон «Игра жизни» Конвей?

0) У Вас есть матрица цветных точек (значение RGB) 1) Если соседняя ячейка имеет более низкое значение X, чем ваш Y, положить Y = 0 на этой ячейке (где X и Y являются красный || Зеленый || Синий) 2) Красный бьет Зеленый бьет Синий бьет Красный

Что я делаю сейчас это просто происходит по ячейке, проверяя, соблюдены ли вышеприведенные правила. Тем не менее, поведение это не совсем то, что я намеревался, так как иногда ячейки в первых рядах имеют преимущество перед теми, что находятся в конечных строках.

Может ли многопоточность предотвратить это (скажем, запуск двух потоков, один из которых начинается в первой ячейке, а другой на последнем)? Пожалуйста, помилуй мое невежество на параллелизм, но я чувствовал, что это хороший способ начать работать с ним.

ответ

6

Я предполагаю, что вы обновляете матрицу inplace, тогда как вы должны скопировать отслеживание старого состояния матрицы, обновляя новую, а затем заменяя исходную на обновленную. Таким образом, вы не будете обновлять некоторые ячейки, а затем на следующей строке проверяете их значения. Таким образом, это была бы проблема с алгоритмом, не связанная с программированием (и, следовательно, многопоточность не может помочь).

+1

Но после того, как вы изменили использование второй матрицы, это было бы чем-то, что могло бы значительно ускориться при многопоточности.Если вы создали два потока, один из которых выполняет верхнюю половину, а второй делает нижнюю половину (чтобы они никогда не писали в одно и то же пространство памяти), вам вообще не понадобилась бы синхронизация - они оба будут летать на полной скорости. –

+0

Спасибо за совет. Действительно, я обновлял матрицу ipso facto, а не сохранял изменения и применял их в конце. Я изменю его, используя идею DeadMG. @Bill K: Вы имеете в виду использование многопоточности для применения изменений от новой матрицы в исходной матрице? –

+0

@Bill K: Конечно, вопрос был о многопоточности и первом дисбалансе строк. @ Gastón: Вы можете представить несколько способов многопоточной программы. Но в этом случае у вас будет один поток для печати текущего состояния вашей игры, а затем, если ваша матрица большая, вы можете иметь несколько потоков для обновления разделяемой части матрицы. Например, с двумя потоками вы можете обновлять половинки новой матрицы, одновременно считывая одну и ту же исходную матрицу, а затем копировать в исходную матрицу, когда оба потока завершают работу. – Scharron

1

Вам будет лучше адаптировать ваш алгоритм, чтобы предотвратить это.

Опираясь на многопоточность, чтобы изменить поведение, это не очень хорошо. Это, по сути, пытается ввести условие гонки в ваш код. Как правило, при добавлении многопоточности в алгоритм, первый приоритет равен , предотвращает любые изменения в поведении.

При попытке использовать условия гонки для изменения поведения вы делаете это очень недетерминированным, но не в хорошем смысле. Вам будет гораздо лучше попытаться найти другое решение (возможно, используя генератор псевдослучайных чисел и т. Д.), А затем внедрить многопоточность, чтобы сделать ее быстрее (надеюсь, без влияния на результаты).

3

№ Ваша проблема - это неотъемлемый недостаток. У вас есть проблема в том, что вы используете промежуточные результаты, т. Е. Изменение в одной ячейке немедленно влияет на следующую ячейку в этом обновлении. Это не должно. Вы должны создать новую матрицу, сохранить там измененные значения и затем поменять их так, чтобы загружались новые значения. Повторение.

+0

Да, вы правы. Сначала я подумал о том, что очередь хранит изменения, и как только все ячейки будут обработаны, начните разворачивать и применять изменения. В конце концов я отказался от него (плохой ход :)), но идеи похожи (хотя ваш кажется более простым). –

0

Это зависит от того, какую часть обработки вы выберете для многопоточности. Пример многопоточности prototypical - это множитель матрицы. Вы можете в принципе разбить его на квадранты и рассчитать один квадрант в каждом потоке без обмена информацией, кроме исходной матрицы. Обратите внимание, что Game of Life - это редкая матрица, и may or may not выигрывают от многопоточности.

Однако, если вы решите это сделать, имейте в виду, что все должно подсчитывать, что нужно для «следующего поворота», и поместить его в новую матрицу при свопинге в матрицу (желательно не копировать, просто измените указатель где-нибудь) в конце хода, чтобы один поток не менял значения, которые другие должны выполнять своими вычислениями. Таким образом, нить не может быть позволена «обогнать друг друга». Это может означать, что он оказывается неэффективным для работы с несколькими потоками - ваш пробег может отличаться.