@mytec: iter2.3 multithreading p1 done
This commit is contained in:
@@ -53,6 +53,9 @@ from app.services.vegetation_service import vegetation_service, VegetationArea
|
||||
from app.services.weather_service import weather_service
|
||||
from app.services.indoor_service import indoor_service
|
||||
from app.services.atmospheric_service import atmospheric_service
|
||||
from app.services.parallel_coverage_service import (
|
||||
calculate_coverage_parallel, get_cpu_count
|
||||
)
|
||||
|
||||
|
||||
class CoveragePoint(BaseModel):
|
||||
@@ -349,19 +352,47 @@ class CoverageService:
|
||||
f"pre-computed {len(grid)} elevations")
|
||||
_clog(f"━━━ PHASE 2 done: {terrain_time:.1f}s ━━━")
|
||||
|
||||
# ━━━ PHASE 3: Point calculation (sync, in thread pool) ━━━
|
||||
_clog(f"━━━ PHASE 3: Calculating {len(grid)} points (threaded) ━━━")
|
||||
# ━━━ PHASE 3: Point calculation ━━━
|
||||
dominant_path_service._log_count = 0 # Reset diagnostic counter
|
||||
t_points = time.time()
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
points, timing = await loop.run_in_executor(
|
||||
None,
|
||||
self._run_point_loop,
|
||||
grid, site, settings, buildings, streets,
|
||||
spatial_idx, water_bodies, vegetation_areas,
|
||||
site_elevation, point_elevations
|
||||
)
|
||||
use_parallel = len(grid) > 100 and get_cpu_count() > 1
|
||||
num_workers = get_cpu_count()
|
||||
|
||||
if use_parallel:
|
||||
_clog(f"━━━ PHASE 3: Calculating {len(grid)} points "
|
||||
f"(PARALLEL, {num_workers} workers) ━━━")
|
||||
|
||||
try:
|
||||
loop = asyncio.get_event_loop()
|
||||
result_dicts, timing = await loop.run_in_executor(
|
||||
None,
|
||||
calculate_coverage_parallel,
|
||||
grid, point_elevations,
|
||||
site.model_dump(), settings.model_dump(),
|
||||
self.terrain._tile_cache,
|
||||
buildings, streets, water_bodies, vegetation_areas,
|
||||
site_elevation, num_workers, _clog,
|
||||
)
|
||||
|
||||
# Convert dicts back to CoveragePoint objects
|
||||
points = [CoveragePoint(**d) for d in result_dicts]
|
||||
|
||||
except Exception as e:
|
||||
_clog(f"Parallel failed ({e}), falling back to sequential")
|
||||
use_parallel = False
|
||||
|
||||
if not use_parallel:
|
||||
_clog(f"━━━ PHASE 3: Calculating {len(grid)} points (sequential) ━━━")
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
points, timing = await loop.run_in_executor(
|
||||
None,
|
||||
self._run_point_loop,
|
||||
grid, site, settings, buildings, streets,
|
||||
spatial_idx, water_bodies, vegetation_areas,
|
||||
site_elevation, point_elevations
|
||||
)
|
||||
|
||||
points_time = time.time() - t_points
|
||||
total_time = time.time() - calc_start
|
||||
@@ -375,13 +406,17 @@ class CoverageService:
|
||||
_clog(f" Point calc: {points_time:.1f}s "
|
||||
f"({points_time/max(1,len(grid))*1000:.1f}ms/point)")
|
||||
_clog(f" TOTAL: {total_time:.1f}s")
|
||||
_clog(f" Mode: {'parallel (' + str(num_workers) + ' workers)' if use_parallel else 'sequential'}")
|
||||
_clog(f" Tiles in memory: {len(self.terrain._tile_cache)}")
|
||||
if any(v > 0.001 for v in timing.values()):
|
||||
_clog("=== PER-STEP BREAKDOWN ===")
|
||||
for step, dt in timing.items():
|
||||
if dt > 0.001:
|
||||
_clog(f" {step:20s} {dt:.3f}s "
|
||||
f"({dt/max(1,len(grid))*1000:.2f}ms/point)")
|
||||
if isinstance(dt, float):
|
||||
_clog(f" {step:20s} {dt:.3f}s "
|
||||
f"({dt/max(1,len(grid))*1000:.2f}ms/point)")
|
||||
else:
|
||||
_clog(f" {step:20s} {dt}")
|
||||
|
||||
return points
|
||||
|
||||
|
||||
Reference in New Issue
Block a user