Skip to content

Commit d96c78f

Browse files
stepanchegfacebook-github-bot
authored andcommitted
ProfileData::merge bytecode
Summary: Implement merge of bytecode profile results. `buck2 profile analysis --mode=bytecode --recursive` works now. Bytecode profile is not very helpful for typical buck users, but it was easier to implement, and we need to start somewhere. Reviewed By: bobyangyf Differential Revision: D38681490 fbshipit-source-id: 832234c172121b31470cb6d84d0cad4407a934fb
1 parent 1f83759 commit d96c78f

File tree

2 files changed

+120
-1
lines changed

2 files changed

+120
-1
lines changed

starlark/src/eval/runtime/profile/bc.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use std::collections::HashMap;
2121
use std::iter::Sum;
2222
use std::mem;
23+
use std::ops::AddAssign;
2324

2425
use gazebo::prelude::*;
2526

@@ -45,24 +46,55 @@ impl<'a> Sum<&'a BcInstrStat> for BcInstrStat {
4546
}
4647
}
4748

49+
impl<'a> AddAssign<&'a BcInstrStat> for BcInstrStat {
50+
fn add_assign(&mut self, other: &'a BcInstrStat) {
51+
let BcInstrStat { count } = other;
52+
self.count += count;
53+
}
54+
}
55+
4856
#[derive(Default, Clone, Copy, Dupe, Debug)]
4957
struct BcInstrPairsStat {
5058
count: u64,
5159
// We are not measuring time here, because even time for single opcode
5260
// is not very accurate or helpful, and time for pairs is even less helpful.
5361
}
5462

63+
impl<'a> AddAssign<&'a BcInstrPairsStat> for BcInstrPairsStat {
64+
fn add_assign(&mut self, other: &'a BcInstrPairsStat) {
65+
let BcInstrPairsStat { count } = other;
66+
self.count += count;
67+
}
68+
}
69+
5570
#[derive(Clone, Debug)]
5671
pub(crate) struct BcProfileData {
5772
by_instr: [BcInstrStat; BcOpcode::COUNT],
5873
}
5974

75+
impl<'a> AddAssign<&'a BcProfileData> for BcProfileData {
76+
fn add_assign(&mut self, rhs: &'a BcProfileData) {
77+
for (lhs, rhs) in self.by_instr.iter_mut().zip(rhs.by_instr.iter()) {
78+
*lhs += rhs;
79+
}
80+
}
81+
}
82+
6083
#[derive(Default, Clone, Debug)]
6184
pub(crate) struct BcPairsProfileData {
6285
last: Option<BcOpcode>,
6386
by_instr: HashMap<[BcOpcode; 2], BcInstrPairsStat>,
6487
}
6588

89+
impl<'a> AddAssign<&'a BcPairsProfileData> for BcPairsProfileData {
90+
fn add_assign(&mut self, rhs: &'a BcPairsProfileData) {
91+
self.last = None;
92+
for (pair, stat) in &rhs.by_instr {
93+
*self.by_instr.entry(*pair).or_default() += stat;
94+
}
95+
}
96+
}
97+
6698
// Derive doesn't work here.
6799
impl Default for BcProfileData {
68100
fn default() -> Self {
@@ -104,6 +136,14 @@ impl BcProfileData {
104136
}
105137
csv.finish()
106138
}
139+
140+
pub(crate) fn merge<'a>(iter: impl IntoIterator<Item = &'a BcProfileData>) -> BcProfileData {
141+
let mut sum = BcProfileData::default();
142+
for profile in iter {
143+
sum += profile;
144+
}
145+
sum
146+
}
107147
}
108148

109149
impl BcPairsProfileData {
@@ -138,6 +178,16 @@ impl BcPairsProfileData {
138178
}
139179
csv.finish()
140180
}
181+
182+
pub(crate) fn merge<'a>(
183+
iter: impl IntoIterator<Item = &'a BcPairsProfileData>,
184+
) -> BcPairsProfileData {
185+
let mut sum = BcPairsProfileData::default();
186+
for profile in iter {
187+
sum += profile;
188+
}
189+
sum
190+
}
141191
}
142192

143193
enum BcProfileDataMode {
@@ -210,6 +260,8 @@ mod tests {
210260
use crate::environment::Globals;
211261
use crate::environment::Module;
212262
use crate::eval::bc::opcode::BcOpcode;
263+
use crate::eval::runtime::profile::bc::BcPairsProfileData;
264+
use crate::eval::runtime::profile::bc::BcProfileData;
213265
use crate::eval::Evaluator;
214266
use crate::eval::ProfileMode;
215267
use crate::syntax::AstModule;
@@ -261,4 +313,18 @@ mod tests {
261313
csv
262314
);
263315
}
316+
317+
#[test]
318+
fn test_bc_profile_data_merge() {
319+
let bc = BcProfileData::default();
320+
// Smoke test.
321+
BcProfileData::merge([&bc, &bc, &bc]);
322+
}
323+
324+
#[test]
325+
fn test_bc_pairs_profile_data_merge() {
326+
let bc = BcPairsProfileData::default();
327+
// Smoke test.
328+
BcPairsProfileData::merge([&bc, &bc, &bc]);
329+
}
264330
}

starlark/src/eval/runtime/profile/data.rs

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,59 @@ impl ProfileData {
108108
return Err(ProfileDataError::DifferentProfileModes.into());
109109
}
110110
}
111-
Err(ProfileDataError::MergeNotImplemented(profile_mode.dupe()).into())
111+
let profile = match &profile_mode {
112+
ProfileMode::Bytecode => {
113+
let profiles = profiles.try_map(|p| match &p.profile {
114+
ProfileDataImpl::Bc(bc) => Ok(&**bc),
115+
_ => Err(ProfileDataError::ProfileDataNotConsistent),
116+
})?;
117+
let profile = BcProfileData::merge(profiles);
118+
ProfileDataImpl::Bc(box profile)
119+
}
120+
ProfileMode::BytecodePairs => {
121+
let profiles = profiles.try_map(|p| match &p.profile {
122+
ProfileDataImpl::BcPairs(bc_pairs) => Ok(bc_pairs),
123+
_ => Err(ProfileDataError::ProfileDataNotConsistent),
124+
})?;
125+
let profile = BcPairsProfileData::merge(profiles);
126+
ProfileDataImpl::BcPairs(profile)
127+
}
128+
profile_mode => {
129+
return Err(ProfileDataError::MergeNotImplemented(profile_mode.dupe()).into());
130+
}
131+
};
132+
Ok(ProfileData {
133+
profile_mode,
134+
profile,
135+
})
136+
}
137+
}
138+
139+
#[cfg(test)]
140+
mod tests {
141+
use crate::eval::runtime::profile::bc::BcPairsProfileData;
142+
use crate::eval::runtime::profile::bc::BcProfileData;
143+
use crate::eval::runtime::profile::data::ProfileDataImpl;
144+
use crate::eval::ProfileData;
145+
use crate::eval::ProfileMode;
146+
147+
#[test]
148+
fn merge_bc() {
149+
let profile = ProfileData {
150+
profile_mode: ProfileMode::Bytecode,
151+
profile: ProfileDataImpl::Bc(box BcProfileData::default()),
152+
};
153+
// Smoke.
154+
ProfileData::merge([&profile, &profile]).unwrap();
155+
}
156+
157+
#[test]
158+
fn merge_bc_pairs() {
159+
let profile = ProfileData {
160+
profile_mode: ProfileMode::BytecodePairs,
161+
profile: ProfileDataImpl::BcPairs(BcPairsProfileData::default()),
162+
};
163+
// Smoke.
164+
ProfileData::merge([&profile, &profile]).unwrap();
112165
}
113166
}

0 commit comments

Comments
 (0)