// Standalone throughput probe, not VoxelForge's generator or an Unreal integration. // Build from a VS 2022 x64 Native Tools prompt: // cl /nologo /O2 /std:c++20 /EHsc /arch:AVX2 brick_kernel.cpp /Fe:brick_kernel.exe #include #include #include #include #include #include #include #include constexpr int N = 256, B = 8, NB = N / B; #ifndef VF_WORKERS #define VF_WORKERS 8 #endif struct Sphere { int x, y, z, r; }; static std::array spheres; static std::vector field(size_t(N) * N * N); static std::vector reference_sign(size_t(N) * N * N); static volatile uint64_t sink = 0; static uint32_t hash3(int x, int y, int z, uint32_t seed) { uint32_t h = seed ^ (uint32_t(x) * 0x9e3779b1u) ^ (uint32_t(y) * 0x85ebca77u) ^ (uint32_t(z) * 0xc2b2ae3du); h ^= h >> 16; h *= 0x7feb352du; h ^= h >> 15; h *= 0x846ca68bu; return h ^ (h >> 16); } // Integer lattice noise: fixed shifts and products; no FP/CRT/FMA. static int noise(int x, int y, int z) { int sum = 0; for (int octave = 0; octave != 3; ++octave) { int s = 16 >> octave, ix = x / s, iy = y / s, iz = z / s; int fx = (x % s) * 256 / s, fy = (y % s) * 256 / s, fz = (z % s) * 256 / s; uint32_t seed = 1337u + uint32_t(octave) * 17u; int yz[2]; for (int dz = 0; dz != 2; ++dz) { int yy[2]; for (int dy = 0; dy != 2; ++dy) { int a = int(hash3(ix, iy + dy, iz + dz, seed) & 255u); int b = int(hash3(ix + 1, iy + dy, iz + dz, seed) & 255u); yy[dy] = a + ((b - a) * fx >> 8); } yz[dz] = yy[0] + ((yy[1] - yy[0]) * fy >> 8); } int v = yz[0] + ((yz[1] - yz[0]) * fz >> 8); sum += (v - 128) >> octave; } return sum; // in [-224, 222], conservatively use +/-224. } static int density(int x, int y, int z) { int d = -10000; for (const Sphere& s : spheres) { int dx=x-s.x, dy=y-s.y, dz=z-s.z; int q=s.r*s.r-dx*dx-dy*dy-dz*dz; d=std::max(d,q); } return d + noise(x,y,z); } static size_t at(int x,int y,int z) { return (size_t(z)*N+y)*N+x; } template static double run(F&& f) { auto a=std::chrono::steady_clock::now(); f(); return std::chrono::duration(std::chrono::steady_clock::now()-a).count(); } static void parallel_z(auto fn) { std::array t; for (int i=0;i>8)&255u),int((h>>16)&255u), 12+int((h>>24)%16u)}; } for(int trial=0;trial<3;++trial) { double full=run([]{parallel_z([](int lo,int hi){ for(int z=lo;z0; // Conservative sphere/brick bounds with a +/-224 noise interval. std::array kind{}; size_t solid=0,air=0,mixed=0; double classify=run([&]{ for(int bz=0;bz=0); definitelyAir |= (s.r*s.r-far2-224>0); } uint8_t k=definitelyAir?2:(possiblyAir?1:0); kind[(size_t(bz)*NB+by)*NB+bx]=k; if(k==0)++solid; else if(k==2)++air; else ++mixed; } }); std::printf("classify ms=%.3f solid=%zu air=%zu mixed=%zu total=%zu\n",classify,solid,air,mixed,kind.size()); for(int trial=0;trial<3;++trial) { double sparse=run([&]{parallel_z([&](int lo,int hi){ for(int bz=lo/B;bz0)); std::printf("sign mismatches=%zu of %zu\n",mismatches,field.size()); }