Skip to content

Commit 6a19ba8

Browse files
committed
fix: 部分场景fps测量过大
1 parent eadf83f commit 6a19ba8

File tree

5 files changed

+61
-23
lines changed

5 files changed

+61
-23
lines changed

Diff for: examples/simple-analyzer/src/main.rs

+21-5
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,13 @@
1616
* You should have received a copy of the GNU General Public License
1717
* along with this program. If not, see <https://www.gnu.org/licenses/>.
1818
*/
19-
use std::sync::{
20-
atomic::{AtomicBool, Ordering},
21-
Arc,
19+
use std::{
20+
collections::VecDeque,
21+
sync::{
22+
atomic::{AtomicBool, Ordering},
23+
Arc,
24+
},
25+
time::Duration,
2226
};
2327

2428
use anyhow::Result;
@@ -50,9 +54,21 @@ fn main() -> Result<()> {
5054
})?;
5155
}
5256

57+
let mut buffer = VecDeque::with_capacity(120);
58+
5359
while running.load(Ordering::Acquire) {
54-
if let Some((_, frametime)) = analyzer.recv() {
55-
println!("frametime: {frametime:?}");
60+
if let Some((pid, frametime)) = analyzer.recv() {
61+
println!("frametime: {frametime:?}, pid: {pid}");
62+
if buffer.len() >= 120 {
63+
buffer.pop_back();
64+
}
65+
buffer.push_front(frametime);
66+
if buffer.len() == 120 {
67+
let fps = 1.0
68+
/ (buffer.iter().copied().sum::<Duration>() / buffer.len() as u32)
69+
.as_secs_f64();
70+
println!("{fps}");
71+
}
5672
}
5773
}
5874

Diff for: frame-analyzer-ebpf-common/src/lib.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@
2121
#[repr(C)]
2222
pub struct FrameSignal {
2323
pub ktime_ns: u64,
24+
pub buffer: usize,
2425
}
2526

2627
impl FrameSignal {
27-
pub const fn new(ktime_ns: u64) -> Self {
28-
Self { ktime_ns }
28+
pub const fn new(ktime_ns: u64, buffer: usize) -> Self {
29+
Self { ktime_ns, buffer }
2930
}
3031
}

Diff for: frame-analyzer-ebpf/src/main.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ pub fn frame_analyzer_ebpf(ctx: ProbeContext) -> u32 {
3939
}
4040
}
4141

42-
fn try_frame_analyzer_ebpf(_ctx: ProbeContext) -> Result<u32, u32> {
42+
fn try_frame_analyzer_ebpf(ctx: ProbeContext) -> Result<u32, u32> {
4343
if let Some(mut entry) = RING_BUF.reserve::<FrameSignal>(0) {
4444
let ktime_ns = unsafe { bpf_ktime_get_ns() };
45-
entry.write(FrameSignal::new(ktime_ns));
45+
entry.write(FrameSignal::new(ktime_ns, ctx.arg::<usize>(0).unwrap()));
4646
entry.submit(0);
4747
}
4848

Diff for: frame-analyzer/src/analyze_target.rs

+33-12
Original file line numberDiff line numberDiff line change
@@ -16,37 +16,58 @@
1616
* You should have received a copy of the GNU General Public License
1717
* along with this program. If not, see <https://www.gnu.org/licenses/>.
1818
*/
19-
use std::{ptr, time::Duration};
19+
use std::{
20+
collections::{HashMap, VecDeque},
21+
ptr,
22+
time::Duration,
23+
};
2024

2125
use frame_analyzer_ebpf_common::FrameSignal;
2226

23-
use crate::{error::Result, uprobe::UprobeHandler};
27+
use crate::uprobe::UprobeHandler;
2428

2529
pub struct AnalyzeTarget {
2630
pub uprobe: UprobeHandler,
27-
ktime_us_last: Option<u64>,
31+
buffers: HashMap<usize, (u64, VecDeque<Duration>)>,
2832
}
2933

3034
impl AnalyzeTarget {
3135
pub fn new(uprobe: UprobeHandler) -> Self {
3236
Self {
3337
uprobe,
34-
ktime_us_last: None,
38+
buffers: HashMap::new(),
3539
}
3640
}
3741

38-
pub fn update(&mut self) -> Result<Duration> {
39-
let mut frametime = 0;
40-
if let Some(item) = self.uprobe.ring()?.next() {
41-
let frame = unsafe { trans(&item) };
42+
pub fn update(&mut self) -> Option<Duration> {
43+
let mut ring = self.uprobe.ring().unwrap();
44+
let item = ring.next()?;
45+
let event = unsafe { trans(&item) };
46+
if let Some((timestamp, buffer)) = self.buffers.get_mut(&event.buffer) {
47+
let frametime = event.ktime_ns.saturating_sub(*timestamp);
48+
*timestamp = event.ktime_ns;
4249

43-
if let Some(ktime_us_last) = self.ktime_us_last {
44-
frametime = frame.ktime_ns.saturating_sub(ktime_us_last);
50+
if buffer.len() >= 144 {
51+
buffer.pop_back();
4552
}
46-
self.ktime_us_last = Some(frame.ktime_ns);
53+
54+
buffer.push_front(Duration::from_nanos(frametime));
55+
} else {
56+
self.buffers
57+
.insert(event.buffer, (event.ktime_ns, VecDeque::with_capacity(144)));
4758
}
4859

49-
Ok(Duration::from_nanos(frametime))
60+
if self.buffers.get(&event.buffer)
61+
== self
62+
.buffers
63+
.values()
64+
.filter(|(_, buffer)| buffer.len() == 144)
65+
.min_by_key(|(_, buffer)| buffer.iter().copied().sum::<Duration>())
66+
{
67+
self.buffers.get(&event.buffer)?.1.front().copied()
68+
} else {
69+
None
70+
}
5071
}
5172
}
5273

Diff for: frame-analyzer/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ impl Analyzer {
271271
}
272272

273273
let pid = self.buffer.pop_front()?;
274-
let frametime = self.map.get_mut(&pid)?.update().ok()?;
274+
let frametime = self.map.get_mut(&pid)?.update()?;
275275

276276
Some((pid, frametime))
277277
}
@@ -315,7 +315,7 @@ impl Analyzer {
315315
}
316316

317317
let pid = self.buffer.pop_front()?;
318-
let frametime = self.map.get_mut(&pid)?.update().ok()?;
318+
let frametime = self.map.get_mut(&pid)?.update()?;
319319

320320
Some((pid, frametime))
321321
}

0 commit comments

Comments
 (0)