Я пытаюсь смоделировать множество машин Тьюринга с двумя состояниями и тремя символами (лента в одном направлении). Каждая симуляция будет иметь разные входные данные и будет выполняться в течение фиксированного количества шагов. Текущим узким местом в программе, похоже, является симулятор, занимающий тонну памяти на машинах Тьюринга, которые не останавливаются.
Задача состоит в том, чтобы смоделировать около 650 000 ТМ, каждая из которых имеет около 200 непустых входных данных. Максимальное количество шагов, которые я пытаюсь выполнить, составляет 1 миллиард (10 ** 9).
Ниже приведен код, который я запускаю. vector<vector<int> > TM
— это таблица переходов.
vector<int> fast_simulate(vector<vector<int> > TM, string TM_input, int steps) {
/* Return the state reached after supplied steps */
vector<int> tape = itotape(TM_input);
int head = 0;
int current_state = 0;
int halt_state = 2;
for(int i = 0; i < steps; i++){
// Read from tape
if(head >= tape.size()) {
tape.push_back(2);
}
int cell = tape[head];
int data = TM[current_state][cell]; // get transition for this state/input
int move = data % 2;
int write = (data % 10) % 3;
current_state = data / 10;
if(current_state == halt_state) {
// This highlights the last place that is written to in the tape
tape[head] = 4;
vector<int> res = shorten_tape(tape);
res.push_back(i+1);
return res;
}
// Write to tape
tape[head] = write;
// move head
if(move == 0) {
if(head != 0) {
head--;
}
} else {
head++;
}
}
vector<int> res {-1};
return res;
}
vector<int> itotape(string TM_input) {
vector<int> tape;
for(char &c : TM_input) {
tape.push_back(c - '0');
}
return tape;
}
vector<int> shorten_tape(vector<int> tape) {
/* Shorten the tape by removing unnecessary 2's (blanks) from the end of it.
*/
int i = tape.size()-1;
for(; i >= 0; --i) {
if(tape[i] != 2) {
tape.resize(i+1);
return tape;
}
}
return tape;
}
Можно ли где-нибудь улучшить производительность или использование памяти? Даже снижение на 2% будет иметь заметную разницу.
vector
по значению, таким образом, активно копируя их. - person ForceBru   schedule 28.03.2017push_back
работаете вitotape
, тем самым изменяя размерtape
нагрузок раз в секунду, что довольно дорого. Обратите внимание, чтоTM_input
— это строка, размер которой вам известен, чтобы вы могли сразу выделить достаточно памяти. - person ForceBru   schedule 28.03.2017TM_input
- этоstd::string
, и он уже «знает» свой размер. Я пытаюсь сказать, что вы уже знаете этот размер вitotape
, поэтому вы можете сразу выделить достаточно памяти дляtape
, а затем заполнить его данными. В настоящее время вы постоянно увеличиваете размерtape
, последовательно выделяя память, что тратит много времени. - person ForceBru   schedule 28.03.2017