Il codice seguente dimostra le curiosità della programmazione multi-thread. In particolare le prestazioni di incremento std::memory_order_relaxed
rispetto a incremento regolare in un singolo thread. Cosa non capisco perché fetch_add (relaxed) single-threaded è due volte più lento di un normale incremento.atomic fetch_add vs add performance
static void BM_IncrementCounterLocal(benchmark::State& state) {
volatile std::atomic_int val2;
while (state.KeepRunning()) {
for (int i = 0; i < 10; ++i) {
DoNotOptimize(val2.fetch_add(1, std::memory_order_relaxed));
}
}
}
BENCHMARK(BM_IncrementCounterLocal)->ThreadRange(1, 8);
static void BM_IncrementCounterLocalInt(benchmark::State& state) {
volatile int val3 = 0;
while (state.KeepRunning()) {
for (int i = 0; i < 10; ++i) {
DoNotOptimize(++val3);
}
}
}
BENCHMARK(BM_IncrementCounterLocalInt)->ThreadRange(1, 8);
uscita:
Benchmark Time(ns) CPU(ns) Iterations ---------------------------------------------------------------------- BM_IncrementCounterLocal/threads:1 59 60 11402509 BM_IncrementCounterLocal/threads:2 30 61 11284498 BM_IncrementCounterLocal/threads:4 19 62 11373100 BM_IncrementCounterLocal/threads:8 17 62 10491608 BM_IncrementCounterLocalInt/threads:1 31 31 22592452 BM_IncrementCounterLocalInt/threads:2 15 31 22170842 BM_IncrementCounterLocalInt/threads:4 8 31 22214640 BM_IncrementCounterLocalInt/threads:8 9 31 21889704
Hai confrontato il codice macchina? –
Devi dire al compilatore che sei in modalità single threaded. –
Sei su un sistema in cui 'memory_order_relaxed' fa qualcosa? Su un x86 no. 'fetch_add' probabilmente emetterà un blocco del bus per rendere l'operazione di aggiunta atomica. 'operator ++' non ha bisogno di farlo. L'istruzione –