Skip to content

Commit 9fb9c65

Browse files
estebanpadillafacebook-github-bot
authored andcommitted
RegCount max registers calculation
Differential Revision: D59494644
1 parent 68bbba5 commit 9fb9c65

File tree

3 files changed

+132
-0
lines changed

3 files changed

+132
-0
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
#pragma once
10+
#include <array>
11+
#include <cstdint>
12+
13+
template <typename T>
14+
class AvgStats {
15+
T sum_ = 0;
16+
uint64_t n_ = 0;
17+
18+
public:
19+
typedef T value_t;
20+
21+
void push(T value) {
22+
sum_ += value;
23+
n_ += 1;
24+
}
25+
inline bool has_value() const {
26+
return n_ != 0;
27+
}
28+
operator T() const {
29+
return sum_ / n_;
30+
}
31+
};
32+
33+
template <typename T, size_t NTap>
34+
class NTapAvgStats {
35+
std::array<double, NTap> hist_;
36+
size_t cur_idx_;
37+
bool ready_;
38+
39+
public:
40+
typedef T value_t;
41+
42+
void push(T value) {
43+
hist_[cur_idx_++] = value;
44+
if (cur_idx_ >= NTap) {
45+
cur_idx_ = 0;
46+
ready_ = true;
47+
}
48+
}
49+
inline bool has_value() const {
50+
return ready_;
51+
}
52+
operator T() const {
53+
double out = 0.0;
54+
for (double x : hist_) {
55+
out += x;
56+
}
57+
out /= NTap;
58+
return out;
59+
}
60+
};

backends/vulkan/tools/gpuinfo/include/utils.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
#include <executorch/backends/vulkan/runtime/api/api.h>
1010

11+
#include "stats.h"
12+
1113
using namespace vkcompute;
1214
using namespace api;
1315

@@ -47,3 +49,48 @@ void ensure_min_niter(
4749
niter = uint32_t(niter * min_time_us / t);
4850
}
4951
}
52+
53+
template <uint32_t NTap>
54+
struct DtJumpFinder {
55+
private:
56+
NTapAvgStats<double, NTap> time_avg_;
57+
AvgStats<double> dtime_avg_;
58+
double compensation_;
59+
double threshold_;
60+
61+
public:
62+
// Compensation is a tiny additive to give on delta time so that the algorithm
63+
// works smoothly when a sequence of identical timing is ingested, which is
64+
// pretty common in our tests. Threshold is simply how many times the new
65+
// delta has to be to be recognized as a deviation.
66+
DtJumpFinder(double compensation = 0.01, double threshold = 10)
67+
: time_avg_(),
68+
dtime_avg_(),
69+
compensation_(compensation),
70+
threshold_(threshold) {}
71+
72+
// Returns true if the delta time regarding to the last data point seems
73+
// normal; returns false if it seems the new data point is too much away from
74+
// the historical records.
75+
bool push(double time) {
76+
if (time_avg_.has_value()) {
77+
double dtime = std::abs(time - time_avg_) + (compensation_ * time_avg_);
78+
if (dtime_avg_.has_value()) {
79+
double ddtime = std::abs(dtime - dtime_avg_);
80+
if (ddtime > threshold_ * dtime_avg_) {
81+
return true;
82+
}
83+
}
84+
dtime_avg_.push(dtime);
85+
}
86+
time_avg_.push(time);
87+
return false;
88+
}
89+
90+
double dtime_avg() const {
91+
return dtime_avg_;
92+
}
93+
double compensate_time() const {
94+
return compensation_ * time_avg_;
95+
}
96+
};

backends/vulkan/tools/gpuinfo/src/app.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414

1515
void reg_count() {
1616
const uint32_t NREG_MIN = 1;
17+
const uint32_t NREG_MAX = 512;
18+
const uint32_t NREG_STEP = 1;
19+
20+
const double COMPENSATE = 0.01;
21+
const double THRESHOLD = 3;
1722

1823
uint32_t NITER;
1924

@@ -43,6 +48,26 @@ void reg_count() {
4348
std::cout << "Calculating NITER..." << std::endl;
4449
ensure_min_niter(1000, NITER, [&]() { return bench(1, 1, NREG_MIN); });
4550
std::cout << "NITER: " << NITER << std::endl;
51+
52+
uint32_t nreg_max;
53+
54+
DtJumpFinder<5> dj(COMPENSATE, THRESHOLD);
55+
uint32_t nreg = NREG_MIN;
56+
for (; nreg <= NREG_MAX; nreg += NREG_STEP) {
57+
double time = bench(1, 1, nreg);
58+
std::cout << "Testing nreg=\t" << nreg << "\tTime=\t" << time << std::endl;
59+
if (dj.push(time)) {
60+
nreg -= NREG_STEP;
61+
nreg_max = nreg;
62+
break;
63+
}
64+
}
65+
if (nreg >= NREG_MAX) {
66+
std::cout << "Unable to conclude a maximal register count" << std::endl;
67+
nreg_max = NREG_STEP;
68+
} else {
69+
std::cout << nreg_max << " available at most" << std::endl;
70+
}
4671
}
4772

4873
int main(int argc, const char** argv) {

0 commit comments

Comments
 (0)