docs: record the benchmark results in the README
This commit is contained in:
parent
f2810a5c52
commit
77425a6e9d
46
README.md
46
README.md
|
|
@ -64,6 +64,51 @@ The features are `foundation`, `physics`, `orbit`, `rf`, `network`, `ops`,
|
|||
everything including `sim`; `ops` is every layer except `sim`, for a project
|
||||
that does not run simulations.
|
||||
|
||||
## Performance
|
||||
|
||||
The three benchmarks are examples of the facade. They run in release mode and
|
||||
depend on nothing outside the workspace, so a build is the compiler and
|
||||
nothing else. The figures below are one run on an AMD Ryzen 7 8845HS (eight
|
||||
cores, sixteen threads); absolute times move with the machine, so compare the
|
||||
ratios within a table. The method, every size in the sweeps and the reasoning
|
||||
behind each conclusion are in
|
||||
[Benchmark method and results](docs/design/bench.md).
|
||||
|
||||
**One call on the hot paths**
|
||||
|
||||
| Path | Per call |
|
||||
| --- | --- |
|
||||
| Hermite ephemeris query | 24 ns |
|
||||
| TEME to Earth-fixed rotation | 27 ns |
|
||||
| Keplerian elements to a state | 38 ns |
|
||||
| Earth-fixed to geodetic | 50 ns |
|
||||
| Link budget C/N0 | 61 ns |
|
||||
| SGP4 propagation, thirty minutes from epoch | 249 ns |
|
||||
| Access search, 120 samples | 7.5 us |
|
||||
| Planning 60 tasks on one resource | 239 us |
|
||||
|
||||
An ephemeris query is an order of magnitude cheaper than the propagation it
|
||||
stands in for, which is why a densely queried track is tabulated once and then
|
||||
interpolated.
|
||||
|
||||
**Growth with size.** A flat cost per unit is what shows the complexity is
|
||||
right:
|
||||
|
||||
- A day of a constellation at a sixty second step is linear in the satellite
|
||||
count: 24 satellites in 8.7 ms, 2016 in 0.68 s, about 234 ns a sample, an
|
||||
exponent of 0.00.
|
||||
- Access search is flat at about 7.3 us a track from 8 to 128 tracks.
|
||||
- Topology construction is about O(n squared) and greedy planning eases from
|
||||
O(n squared) towards O(n); both are limited by their algorithm, and the
|
||||
design note says why.
|
||||
|
||||
**Threads.** The numerical kernels split by satellite. Propagating 2000
|
||||
satellites over a day takes 671 ms on one thread and 85 ms on sixteen, a
|
||||
speedup of 7.9x; access search over 256 tracks reaches 5.3x. Efficiency is
|
||||
about eighty-five percent at eight threads, one per core; sixteen puts two on
|
||||
a core and returns about half of that. Every parallel result equals the serial one,
|
||||
so threading buys throughput and never changes a number.
|
||||
|
||||
## Conventions
|
||||
|
||||
- Toolchain `stable`, edition 2024, rust-version 1.85
|
||||
|
|
@ -124,6 +169,7 @@ crate cannot infer:
|
|||
- [Errors and tolerances](docs/design/errors.md)
|
||||
- [Layer boundaries](docs/design/layers.md)
|
||||
- [Parallelism](docs/design/parallel.md)
|
||||
- [Benchmark method and results](docs/design/bench.md)
|
||||
- [Glossary and formula conventions](docs/design/glossary.md)
|
||||
- [The simulation layer](docs/design/sim.md)
|
||||
|
||||
|
|
|
|||
47
README.zh.md
47
README.zh.md
|
|
@ -62,6 +62,43 @@ apsis-rs = { path = "...", features = ["orbit"] }
|
|||
每个层 feature 自动启用其下层。`full` 启用全部层(含 `sim`);`ops` 等价于除
|
||||
`sim` 以外的所有层,适合不运行仿真的项目。
|
||||
|
||||
## 性能
|
||||
|
||||
三个基准都是门面的 example。它们在 release 下运行,且除本工作区外不依赖任何
|
||||
东西,故一次构建只需要编译器本身。下表是 AMD Ryzen 7 8845HS(8 核 16 线程)
|
||||
上的一次运行;绝对时间随机器变化,应比较同一张表内的比例。方法、每次规模扫描
|
||||
的全部数据以及每条结论的依据见
|
||||
[压测方法与报告](docs/design/bench.zh.md)。
|
||||
|
||||
**热点路径的单次调用**
|
||||
|
||||
| 路径 | 每次调用 |
|
||||
| --- | --- |
|
||||
| Hermite 星历插值查询 | 24 ns |
|
||||
| TEME 到地固系旋转 | 27 ns |
|
||||
| 开普勒根数转状态 | 38 ns |
|
||||
| 地固系转大地坐标 | 50 ns |
|
||||
| 链路预算 C/N0 | 61 ns |
|
||||
| SGP4 传播(历元后 30 分) | 249 ns |
|
||||
| 可见性搜索(120 样本) | 7.5 μs |
|
||||
| 规划 60 个任务(1 资源) | 239 μs |
|
||||
|
||||
星历查询比它所代替的那次传播便宜一个数量级,这正是被密集查询的轨道应先建表
|
||||
再插值的原因。
|
||||
|
||||
**随规模的增长。** 每单位成本持平才说明复杂度正确:
|
||||
|
||||
- 星座一日传播对星数线性:24 星 8.7 ms,2016 星 0.68 s,每样本约 234 ns,
|
||||
增长指数 0.00。
|
||||
- 可见性搜索在 8 到 128 轨之间恒为每轨约 7.3 μs。
|
||||
- 拓扑构建约为 O(n 平方),贪心规划由 O(n 平方) 缓向 O(n);两者都受算法而非
|
||||
实现限制,设计说明给出了原因。
|
||||
|
||||
**并行。** 数值内核按卫星切分。2000 星一日传播单线程 671 ms、16 线程 85 ms,
|
||||
加速 7.9 倍;256 轨的可见性搜索加速 5.3 倍。8 线程每核一线程时效率约八成五;
|
||||
16 线程每核两线程,收益约为一半。并行结果与串行逐位相同,故加速只换来吞吐,
|
||||
从不改变数值。
|
||||
|
||||
## 约定
|
||||
|
||||
- toolchain:`stable`,`edition 2024`,`rust-version 1.85`
|
||||
|
|
@ -120,6 +157,14 @@ GPL-3.0-or-later,见 `LICENSE`。
|
|||
|
||||
`docs/vendor/mathjax` 下内置的 MathJax 为 Apache-2.0,见该目录内的 `LICENSE`。
|
||||
|
||||
## 术语
|
||||
## 文档
|
||||
|
||||
设计说明记录了单个 crate 的读者无法推断的跨 crate 决策:
|
||||
|
||||
- [单位与坐标](docs/design/units.zh.md)
|
||||
- [错误与容差](docs/design/errors.zh.md)
|
||||
- [层边界](docs/design/layers.zh.md)
|
||||
- [并行](docs/design/parallel.zh.md)
|
||||
- [压测方法与报告](docs/design/bench.zh.md)
|
||||
- [术语与公式约定](docs/design/glossary.zh.md)
|
||||
- [仿真层](docs/design/sim.zh.md)
|
||||
|
|
|
|||
|
|
@ -63,14 +63,14 @@ tool, not values across machines.
|
|||
|
||||
| Path | Per call |
|
||||
| --- | --- |
|
||||
| Hermite ephemeris query | 24.5 ns |
|
||||
| TEME to Earth-fixed rotation | 27.2 ns |
|
||||
| Keplerian elements to a state | 37.8 ns |
|
||||
| Earth-fixed to geodetic | 49.4 ns |
|
||||
| Link budget C/N0 | 61.0 ns |
|
||||
| SGP4 propagation, thirty minutes from epoch | 246.7 ns |
|
||||
| Access search, 120 samples | 7.46 us |
|
||||
| Planning 60 tasks on one resource | 240 us |
|
||||
| Hermite ephemeris query | 24.3 ns |
|
||||
| TEME to Earth-fixed rotation | 26.8 ns |
|
||||
| Keplerian elements to a state | 38.1 ns |
|
||||
| Earth-fixed to geodetic | 50.1 ns |
|
||||
| Link budget C/N0 | 60.6 ns |
|
||||
| SGP4 propagation, thirty minutes from epoch | 248.7 ns |
|
||||
| Access search, 120 samples | 7.49 us |
|
||||
| Planning 60 tasks on one resource | 239 us |
|
||||
|
||||
A query against the ephemeris is about ten times cheaper than the
|
||||
propagation it stands in for, which is the reason `apsis-ephemeris` exists:
|
||||
|
|
@ -82,10 +82,10 @@ when a track is queried many times, build the table once and interpolate.
|
|||
|
||||
| Satellites | Cold | Steady | Per sample |
|
||||
| --- | --- | --- | --- |
|
||||
| 24 | 9.1 ms | 8.2 ms | 238 ns |
|
||||
| 240 | 79.5 ms | 82.5 ms | 239 ns |
|
||||
| 1008 | 337.0 ms | 337.0 ms | 232 ns |
|
||||
| **2016** | 675.2 ms | 675.2 ms | 232 ns |
|
||||
| 24 | 8.7 ms | 8.7 ms | 252 ns |
|
||||
| 240 | 80.5 ms | 80.0 ms | 231 ns |
|
||||
| 1008 | 339.5 ms | 339.5 ms | 234 ns |
|
||||
| **2016** | 679.4 ms | 679.4 ms | 234 ns |
|
||||
|
||||
**The cost per sample is flat, an exponent of 0.00**, so one SGP4 propagation
|
||||
is constant time and the whole day is linear in the number of satellites. A
|
||||
|
|
@ -98,20 +98,20 @@ allocation.
|
|||
| Tracks | Per track |
|
||||
| --- | --- |
|
||||
| 8 | 7.3 us |
|
||||
| 128 | 7.4 us |
|
||||
| 128 | 7.3 us |
|
||||
|
||||
**Flat, an exponent of 0.01.** Each track is independent, so the search is
|
||||
**Flat, an exponent of 0.00.** Each track is independent, so the search is
|
||||
linear in the number of satellites.
|
||||
|
||||
### Topology construction and routing
|
||||
|
||||
| Satellites | Per satellite | Exponent |
|
||||
| --- | --- | --- |
|
||||
| 8 | 252 ns | — |
|
||||
| 64 | 2.2 us | 1.19 |
|
||||
| 120 | 5.8 us | 1.52 |
|
||||
| 300 | 34.1 us | 1.94 |
|
||||
| **600** | **193.4 us** | 2.50 |
|
||||
| 8 | 237 ns | — |
|
||||
| 64 | 2.2 us | 1.07 |
|
||||
| 120 | 5.7 us | 1.52 |
|
||||
| 300 | 33.0 us | 1.93 |
|
||||
| **600** | **182.6 us** | 2.47 |
|
||||
|
||||
**Roughly O(n squared).** The cost per satellite grows with the count, the
|
||||
exponent rising from one towards two and a half. The cause is inherent: the
|
||||
|
|
@ -122,10 +122,10 @@ judge. The parallel scan confirms where the time goes.
|
|||
|
||||
| Tasks | Per task | Exponent |
|
||||
| --- | --- | --- |
|
||||
| 60 | 4.6 us | — |
|
||||
| 200 | 14.7 us | 0.96 |
|
||||
| 1000 | 106.7 us | 1.32 |
|
||||
| **2000** | **312.7 us** | 1.55 |
|
||||
| 60 | 4.5 us | — |
|
||||
| 200 | 16.0 us | 1.05 |
|
||||
| 1000 | 108.4 us | 1.33 |
|
||||
| **2000** | **314.1 us** | 1.54 |
|
||||
|
||||
**Roughly O(n squared), easing towards O(n) at size.** A greedy placement
|
||||
arranges tasks in time order and each arrangement is compared against the
|
||||
|
|
@ -138,63 +138,65 @@ defect in the implementation.
|
|||
|
||||
| Satellites | 1 thread | 2 | 4 | 8 | 16 | Best |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| 550 | 299 ms | 1.46x | 2.87x | 4.49x | 7.96x | 7.96x at 16 |
|
||||
| 1000 | 361 ms | 2.01x | 4.03x | 7.88x | 9.94x | 9.94x at 16 |
|
||||
| 2000 | 673 ms | 1.79x | 3.59x | 6.89x | 8.28x | 8.28x at 16 |
|
||||
| 550 | 184 ms | 1.96x | 3.83x | 6.86x | 8.12x | 8.12x at 16 |
|
||||
| 1000 | 336 ms | 1.89x | 3.73x | 6.49x | 8.24x | 8.24x at 16 |
|
||||
| 2000 | 671 ms | 1.89x | 3.74x | 6.61x | 7.93x | 7.93x at 16 |
|
||||
|
||||
**Propagation is embarrassingly parallel.** Every satellite is independent,
|
||||
and two to eight threads come close to linear. Efficiency at sixteen threads
|
||||
falls to about one half, which is the contention of running two threads per
|
||||
core. Eight threads is the better setting, near ninety percent efficiency;
|
||||
sixteen buys more absolute throughput at a lower return.
|
||||
core. Eight threads is the better setting, about eighty-five percent
|
||||
efficiency; sixteen buys more absolute throughput at a lower return.
|
||||
|
||||
### Access search
|
||||
|
||||
| Tracks | 1 thread | 4 | 8 | 16 | Best |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| 64 | 1.08 ms | 2.24x | 2.89x | 2.23x | 2.89x at 8 |
|
||||
| 256 | 2.40 ms | 3.32x | 5.59x | 5.61x | 5.61x at 8 |
|
||||
| 64 | 0.47 ms | 2.74x | 2.68x | 1.87x | 2.74x at 4 |
|
||||
| 256 | 1.95 ms | 3.52x | 4.36x | 5.27x | 5.27x at 16 |
|
||||
|
||||
**The gain is small on a small batch**, because the fixed cost of starting
|
||||
threads dominates when there is little work. At 256 tracks it reaches about
|
||||
5.6x.
|
||||
5.3x.
|
||||
|
||||
### Topology construction, split by phase
|
||||
|
||||
| Satellites | Visibility, parallelisable | Edge fold, serial tail | Best speedup |
|
||||
| --- | --- | --- | --- |
|
||||
| 120 | 0.30 ms | 0.21 ms | 1.48x |
|
||||
| 300 | 1.92 ms | 4.06 ms | about 1.0x |
|
||||
| 120 | 0.31 ms | 0.30 ms | 1.37x |
|
||||
| 300 | 1.93 ms | 3.84 ms | 1.72x |
|
||||
|
||||
**Threading does not help this path.** At 300 satellites the serial edge fold
|
||||
takes more than twice the parallelisable part, and the total barely moves
|
||||
with the thread count. The cause is that `add_edge` scans the edges already
|
||||
stored to reject a duplicate, which makes the insertion itself cubic.
|
||||
**Threading helps this path only a little.** At 300 satellites the serial
|
||||
edge fold takes twice the parallelisable part, so the total gains at most
|
||||
1.7x rather than the near-linear gain of the numerical kernels. The cause is
|
||||
that `add_edge` scans the edges already stored to reject a duplicate, which
|
||||
makes the insertion itself cubic.
|
||||
|
||||
## Conclusions
|
||||
|
||||
| Path | Complexity | Threads | At useful scale |
|
||||
| --- | --- | --- | --- |
|
||||
| SGP4 propagation | O(1) a sample | excellent, about 7x on eight | 2016 satellites a day in 0.7 s, 81 ms on sixteen |
|
||||
| SGP4 propagation | O(1) a sample | excellent, about 8x on sixteen | 2016 satellites a day in 0.68 s, 85 ms on sixteen |
|
||||
| Ephemeris query | O(log n) | follows propagation | 24 ns |
|
||||
| Access search | O(1) a satellite | good, about 5x on eight | 256 tracks in 0.33 ms |
|
||||
| Access search | O(1) a satellite | good, about 5x on sixteen | 256 tracks in 0.37 ms |
|
||||
| Coordinate and link | O(1) | not worth it | 27 to 61 ns |
|
||||
| Task planning | about O(n squared) | serial | 2000 tasks in 0.6 s |
|
||||
| Topology construction | about O(n squared) | **no gain**, a serial tail dominates | 600 satellites in 116 ms |
|
||||
| Task planning | about O(n squared) | serial | 2000 tasks in 0.63 s |
|
||||
| Topology construction | about O(n squared) | limited, a serial tail dominates | 600 satellites in 110 ms |
|
||||
|
||||
**The points that matter**
|
||||
|
||||
1. The numerical kernels are linear and parallelise well. A day over two
|
||||
thousand satellites costs 0.7 seconds on one core and 81 ms on sixteen.
|
||||
thousand satellites costs 0.68 seconds on one core and 85 ms on sixteen.
|
||||
2. Interpolating the ephemeris is about ten times cheaper than propagating,
|
||||
so a densely queried track should be tabulated once.
|
||||
3. Two combined operations are limited by their algorithm rather than by the
|
||||
available cores. Greedy planning is quadratically serial, and the
|
||||
duplicate check on edge insertion squares that quadratic. Neither gains
|
||||
from threading; both need a different algorithm.
|
||||
4. Eight threads is the setting to use. Efficiency is near ninety percent,
|
||||
while sixteen threads falls to about one half because two threads share a
|
||||
core.
|
||||
duplicate check on edge insertion squares that quadratic; the second gains
|
||||
only about 1.7x from threading. Both would need a different algorithm to
|
||||
gain more.
|
||||
4. Eight threads is the better setting for propagation. Efficiency is about
|
||||
eighty-five percent, while sixteen threads falls to about one half because
|
||||
two threads share a core.
|
||||
|
||||
## Reproducing
|
||||
|
||||
|
|
|
|||
|
|
@ -55,14 +55,14 @@ cargo run --release -p apsis-rs --features full --example bench_parallel
|
|||
|
||||
| 路径 | 每次调用 |
|
||||
| --- | --- |
|
||||
| Hermite 星历插值查询 | 24.5 ns |
|
||||
| TEME 到地固系旋转 | 27.2 ns |
|
||||
| 开普勒根数转状态 | 37.8 ns |
|
||||
| 地固系转大地坐标 | 49.4 ns |
|
||||
| 链路预算 C/N0 | 61.0 ns |
|
||||
| SGP4 传播(历元后 30 分) | 246.7 ns |
|
||||
| 可见性搜索(120 样本) | 7.46 μs |
|
||||
| 规划 60 个任务(1 资源) | 240 μs |
|
||||
| Hermite 星历插值查询 | 24.3 ns |
|
||||
| TEME 到地固系旋转 | 26.8 ns |
|
||||
| 开普勒根数转状态 | 38.1 ns |
|
||||
| 地固系转大地坐标 | 50.1 ns |
|
||||
| 链路预算 C/N0 | 60.6 ns |
|
||||
| SGP4 传播(历元后 30 分) | 248.7 ns |
|
||||
| 可见性搜索(120 样本) | 7.49 μs |
|
||||
| 规划 60 个任务(1 资源) | 239 μs |
|
||||
|
||||
星历查询比它所替代的 SGP4 传播快约十倍,这正是 `apsis-ephemeris` 存在的理由:
|
||||
一次建表、多次查询时,插值远便宜于传播。
|
||||
|
|
@ -73,10 +73,10 @@ cargo run --release -p apsis-rs --features full --example bench_parallel
|
|||
|
||||
| 星数 | 冷启动 | 稳态 | 每样本 |
|
||||
| --- | --- | --- | --- |
|
||||
| 24 | 9.1 ms | 8.2 ms | 238 ns |
|
||||
| 240 | 79.5 ms | 82.5 ms | 239 ns |
|
||||
| 1008 | 337.0 ms | 337.0 ms | 232 ns |
|
||||
| **2016** | 675.2 ms | 675.2 ms | 232 ns |
|
||||
| 24 | 8.7 ms | 8.7 ms | 252 ns |
|
||||
| 240 | 80.5 ms | 80.0 ms | 231 ns |
|
||||
| 1008 | 339.5 ms | 339.5 ms | 234 ns |
|
||||
| **2016** | 679.4 ms | 679.4 ms | 234 ns |
|
||||
|
||||
**每样本成本恒定(增长指数 0.00)**,即 SGP4 单次传播是 O(1),总时间线性于星数。
|
||||
两千余星的一日覆盖约 0.7 秒。冷启动与稳态几乎相同,说明该路径没有显著的
|
||||
|
|
@ -87,19 +87,19 @@ cargo run --release -p apsis-rs --features full --example bench_parallel
|
|||
| 轨数 | 每星 |
|
||||
| --- | --- |
|
||||
| 8 | 7.3 μs |
|
||||
| 128 | 7.4 μs |
|
||||
| 128 | 7.3 μs |
|
||||
|
||||
**恒定(增长指数 0.01)**,每条轨道独立,线性于星数。
|
||||
**恒定(增长指数 0.00)**,每条轨道独立,线性于星数。
|
||||
|
||||
### 拓扑构建与路由(4500 km 链路)
|
||||
|
||||
| 星数 | 每星 | 增长指数 |
|
||||
| --- | --- | --- |
|
||||
| 8 | 252 ns | — |
|
||||
| 64 | 2.2 μs | 1.19 |
|
||||
| 120 | 5.8 μs | 1.52 |
|
||||
| 300 | 34.1 μs | 1.94 |
|
||||
| **600** | **193.4 μs** | 2.50 |
|
||||
| 8 | 237 ns | — |
|
||||
| 64 | 2.2 μs | 1.07 |
|
||||
| 120 | 5.7 μs | 1.52 |
|
||||
| 300 | 33.0 μs | 1.93 |
|
||||
| **600** | **182.6 μs** | 2.47 |
|
||||
|
||||
**约 O(n²)**。每星成本随星数增长,指数从 1 升到 2.5。成因是几何判定本身
|
||||
就是全对检查:n 颗星有 n² 对要判断。并行扫描证实瓶颈在此。
|
||||
|
|
@ -108,10 +108,10 @@ cargo run --release -p apsis-rs --features full --example bench_parallel
|
|||
|
||||
| 任务数 | 每任务 | 增长指数 |
|
||||
| --- | --- | --- |
|
||||
| 60 | 4.6 μs | — |
|
||||
| 200 | 14.7 μs | 0.96 |
|
||||
| 1000 | 106.7 μs | 1.32 |
|
||||
| **2000** | **312.7 μs** | 1.55 |
|
||||
| 60 | 4.5 μs | — |
|
||||
| 200 | 16.0 μs | 1.05 |
|
||||
| 1000 | 108.4 μs | 1.33 |
|
||||
| **2000** | **314.1 μs** | 1.54 |
|
||||
|
||||
**约 O(n²),大 n 时趋向 O(n)**。贪心放置本质上按时间序逐个安排,每次放置
|
||||
都要与已放置的 placement 比较,故二次是算法本身而非实现缺陷。
|
||||
|
|
@ -122,53 +122,53 @@ cargo run --release -p apsis-rs --features full --example bench_parallel
|
|||
|
||||
| 星数 | 1 线程 | 2 | 4 | 8 | 16 | 最佳加速 |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| 550 | 299 ms | 1.46× | 2.87× | 4.49× | 7.96× | 7.96× (16) |
|
||||
| 1000 | 361 ms | 2.01× | 4.03× | 7.88× | 9.94× | 9.94× (16) |
|
||||
| 2000 | 673 ms | 1.79× | 3.59× | 6.89× | 8.28× | 8.28× (16) |
|
||||
| 550 | 184 ms | 1.96× | 3.83× | 6.86× | 8.12× | 8.12× (16) |
|
||||
| 1000 | 336 ms | 1.89× | 3.73× | 6.49× | 8.24× | 8.24× (16) |
|
||||
| 2000 | 671 ms | 1.89× | 3.74× | 6.61× | 7.93× | 7.93× (16) |
|
||||
|
||||
**传播是 embarrassingly parallel**:每个卫星独立,2 至 8 线程接近线性。
|
||||
16 线程效率降到约 0.5,即超线程带来争用。**推荐 8 线程**(效率 0.9 左右),
|
||||
16 线程效率降到约 0.5,即超线程带来争用。**推荐 8 线程**(效率约 0.85),
|
||||
或 16 线程换取更高绝对吞吐。
|
||||
|
||||
### 可见性搜索
|
||||
|
||||
| 轨数 | 1 线程 | 4 | 8 | 16 | 最佳加速 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| 64 | 1.08 ms | 2.24× | 2.89× | 2.23× | 2.89× (8) |
|
||||
| 256 | 2.40 ms | 3.32× | 5.59× | 5.61× | 5.61× (8) |
|
||||
| 64 | 0.47 ms | 2.74× | 2.68× | 1.87× | 2.74× (4) |
|
||||
| 256 | 1.95 ms | 3.52× | 4.36× | 5.27× | 5.27× (16) |
|
||||
|
||||
**小规模加速有限**,因为线程启动的固定开销在小工作量上占主导。256 轨约 5.6×。
|
||||
**小规模加速有限**,因为线程启动的固定开销在小工作量上占主导。256 轨约 5.3×。
|
||||
|
||||
### 拓扑构建(阶段拆分)
|
||||
|
||||
| 星数 | 可见性(可并行) | 边折叠(串行尾部) | 最佳加速 |
|
||||
| --- | --- | --- | --- |
|
||||
| 120 | 0.30 ms | 0.21 ms | 1.48× |
|
||||
| 300 | 1.92 ms | 4.06 ms | ~1.0× |
|
||||
| 120 | 0.31 ms | 0.30 ms | 1.37× |
|
||||
| 300 | 1.93 ms | 3.84 ms | 1.72× |
|
||||
|
||||
**并行化无法解决该路径**。300 星时串行的边折叠占 4.06 ms,是可并行部分的
|
||||
两倍有余,总时间几乎不随线程数变化。根因是 `add_edge` 查重时线性扫描已有边,
|
||||
使插入本身成为 O(n³)。
|
||||
**该路径并行收益有限**。300 星时串行的边折叠占 3.84 ms,是可并行部分的两倍,
|
||||
故总时间最多加速约 1.7 倍,远不及数值内核的接近线性。根因是 `add_edge` 查重时
|
||||
线性扫描已有边,使插入本身成为 O(n³)。
|
||||
|
||||
## 结论
|
||||
|
||||
| 路径 | 复杂度 | 并行性 | 实用规模表现 |
|
||||
| --- | --- | --- | --- |
|
||||
| SGP4 传播 | O(1)/样本 | 优秀,8 线程 ~7× | 2016 星一日 0.7 s;16 线程 81 ms |
|
||||
| SGP4 传播 | O(1)/样本 | 优秀,16 线程 ~8× | 2016 星一日 0.68 s;16 线程 85 ms |
|
||||
| 星历插值查询 | O(log n) | 随传播 | 24 ns/次 |
|
||||
| 可见性搜索 | O(1)/星 | 良好,8 线程 ~5× | 256 轨 0.33 ms |
|
||||
| 可见性搜索 | O(1)/星 | 良好,16 线程 ~5× | 256 轨 0.37 ms |
|
||||
| 坐标与链路 | O(1) | 不必并行 | 27 至 61 ns |
|
||||
| 任务规划 | ~O(n²) | 串行 | 2000 任务 0.6 s |
|
||||
| 拓扑构建 | ~O(n²) | **无效**(串行尾部主导) | 600 星 116 ms |
|
||||
| 任务规划 | ~O(n²) | 串行 | 2000 任务 0.63 s |
|
||||
| 拓扑构建 | ~O(n²) | 收益有限(串行尾部主导) | 600 星 110 ms |
|
||||
|
||||
**要点**
|
||||
|
||||
1. **数值内核是线性且高度可并行的。** 两千余星的一日轨道预测单线程 0.7 秒,
|
||||
16 线程 81 毫秒。
|
||||
1. **数值内核是线性且高度可并行的。** 两千余星的一日轨道预测单线程 0.68 秒,
|
||||
16 线程 85 毫秒。
|
||||
2. **星历插值比传播快十倍**,密集查询场景应先用传播建表再插值。
|
||||
3. **两个组合算法受限于算法而非并行度**:任务规划是贪心的固有二次,拓扑构建的
|
||||
边插入查重是二次的平方。并行化对二者都无能为力,需要改算法。
|
||||
4. **推荐配置 8 线程**:并行效率约 0.9,16 线程因超线程争用降至约 0.5。
|
||||
边插入查重是二次的平方,后者并行化最多只能加速约 1.7 倍。欲再提升需改算法。
|
||||
4. **传播推荐 8 线程**:并行效率约 0.85,16 线程因超线程争用降至约 0.5。
|
||||
|
||||
## 复现
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue