Я запускаю while loop в 4 потоках, в цикле я оцениваю функцию и постепенно увеличиваю счетчик.
while(1) {
int fitness = EnergyFunction::evaluate(sequence);
mutex.lock();
counter++;
mutex.unlock();
}
Когда я запускаю этот цикл, как я сказал в 4 потоках, я получаю ~ 20 000 000 оценок в секунду.
while(1) {
if (dist(mt) == 0) {
sequence[distDim(mt)] = -1;
} else {
sequence[distDim(mt)] = 1;
}
int fitness = EnergyFunction::evaluate(sequence);
mainMTX.lock();
overallGeneration++;
mainMTX.unlock();
}
Если я добавлю некоторую случайную мутацию для последовательности, я получаю ~ 13 000 000 оценок в секунду.
while(1) {
if (dist(mt) == 0) {
sequence[distDim(mt)] = -1;
} else {
sequence[distDim(mt)] = 1;
}
int fitness = EnergyFunction::evaluate(sequence);
mainMTX.lock();
if(fitness < overallFitness)
overallFitness = fitness;
overallGeneration++;
mainMTX.unlock();
}
Но когда я добавляю простую инструкцию if, которая проверяет, будет ли новый фитнес меньше старой, если это правда, замените старую пригодность новой пригодностью.
Но потеря производительности огромна! Теперь я получаю ~ 20 000 оценок в секунду. Если я удаляю случайную мутацию, я также получаю ~ 20 000 оценок в секунду.
Переменная totalFitness объявляется как
extern int overallFitness;
У меня возникают проблемы с выяснением, в чем проблема такой большой потери производительности. Сравнивает ли два int такое время с операцией?
Также я не считаю, что это связано с блокировкой мьютекса.
UPDATE
Эта потеря производительности не была вызвана предсказанием ветвления, но компилятор просто проигнорировал этот вызов int fitness = EnergyFunction::evaluate(sequence);
.
Теперь я добавил volatile
, и компилятор больше не игнорирует вызов.
Также спасибо за указание на неверное предсказание отрасли и atomic<int>
, не знали о них!
Из-за атома я также удаляю часть mutex, поэтому окончательный код выглядит следующим образом:
while(1) {
sequence[distDim(mt)] = lookup_Table[dist(mt)];
fitness = EnergyFunction::evaluate(sequence);
if(fitness < overallFitness)
overallFitness = fitness;
++overallGeneration;
}
Теперь я получаю ~ 25 000 оценок в секунду.