Multi-threaded system inconsistent calculation
Hexlord opened this issue · comments
Describe the bug
Inconsistent system evaluation behavior of multi_threaded system, unpredictable results
Iter.count() is the same
Doint just Count++ inside Iter loop works fine
But this slightly complicated calculation leads to different results based on whether the system is multi_threaded or not, absolute magic
To Reproduce
#include "flecs.h"
#include "inttypes.h"
#include <atomic>
#include <cstdio>
int main() {
struct Comp1 {
int field1;
int field2;
};
{
flecs::world ECS;
ECS.set_threads(8);
std::atomic<uint32_t> Count{0};
ECS.system<Comp1>().multi_threaded(false).iter(
[&](flecs::iter &Iter) {
for (auto Index : Iter) {
auto Entity = Iter.entity(Index);
(void)Entity;
for (int I = 0; I < 100000; ++I) {
Count = Count + 1;
Count = Count - 1;
Count = Count + 1;
}
Count = Count - 100000 + 1;
}
});
for(int i = 0; i < 100; ++i) {
ECS.entity().add<Comp1>();
}
ECS.progress();
printf("Single-threaded system: %u\n", Count.load());
}
{
flecs::world ECS;
ECS.set_threads(8);
std::atomic<uint32_t> Count{0};
ECS.system<Comp1>().multi_threaded(true).iter(
[&](flecs::iter &Iter) {
for (auto Index : Iter) {
auto Entity = Iter.entity(Index);
(void)Entity;
for (int I = 0; I < 100000; ++I) {
Count = Count + 1;
Count = Count - 1;
Count = Count + 1;
}
Count = Count - 100000 + 1;
}
});
for(int i = 0; i < 100; ++i) {
ECS.entity().add<Comp1>();
}
ECS.progress();
printf("Multi-threaded system: %u\n", Count.load());
}
return 0;
}
Expected behavior
/home/sasha/flecs_test/cmake-build-debug/SECore
Single-threaded system: 100
Multi-threaded system: 100
Actual behavior
/home/sasha/flecs_test/cmake-build-debug/SECore
Single-threaded system: 100
Multi-threaded system: 265036 (different every time)
Sorry I am stupid lol, it is read-write op, it is non-atomic :D
This is correct system code and it works correctly
ECS.system<Comp1>().multi_threaded(true).iter(
[&](flecs::iter &Iter) {
for (auto Index : Iter) {
auto Entity = Iter.entity(Index);
(void)Entity;
for (int I = 0; I < 100000; ++I) {
Count++;
Count--;
Count++;
}
Count.fetch_add(-99999);
}
});