@@ -16,6 +16,10 @@ struct A {
1616 int64_t payload;
1717};
1818
19+ constexpr bool is_pow2 (int a) {
20+ return a && ((a & (a - 1 )) == 0 );
21+ }
22+
1923struct Test {
2024 Test (int64_t len, int64_t rep) : rep_(rep * len) {
2125 l.resize (len);
@@ -36,9 +40,12 @@ struct Test {
3640 });
3741 }
3842
43+ template <int unroll=2 >
3944 int64_t run () {
45+ static_assert (is_pow2 (unroll), " unroll factor must be power of 2" );
4046 A* curr = &l[0 ];
4147 int64_t res = 0 ;
48+ #pragma clang loop unroll_count(unroll)
4249 for (int64_t r = 0 ; r < rep_; r++) {
4350 curr = curr->next ;
4451 if (curr->payload % 3 == 0 ) {
@@ -48,95 +55,41 @@ struct Test {
4855 return res;
4956 }
5057
51- int64_t run_unrolled () {
52- A* curr = &l[0 ];
53- int64_t res = 0 ;
54- for (int64_t r = 0 ; r < rep_; r += 4 ) {
55- curr = curr->next ;
56- if (curr->payload % 3 == 0 ) {
57- res += curr->payload ;
58- }
59- curr = curr->next ;
60- if (curr->payload % 3 == 0 ) {
61- res += curr->payload ;
62- }
63- curr = curr->next ;
64- if (curr->payload % 3 == 0 ) {
65- res += curr->payload ;
66- }
67- curr = curr->next ;
68- if (curr->payload % 3 == 0 ) {
69- res += curr->payload ;
70- }
71- }
72- return res;
73- }
7458 private:
7559 std::vector<A> l;
7660 int64_t rep_;
7761};
7862
7963const size_t kSize = (1 << 10 );
8064
81- B63_BENCHMARK (icestorm, n) {
82- pthread_set_qos_class_self_np (QOS_CLASS_BACKGROUND, 0 );
83- Test* t;
84- B63_SUSPEND {
85- t = new Test (kSize , n);
65+ #define BM_UNROLLED (name, qos, unroll ) \
66+ B63_BENCHMARK (name##_u##unroll, n) { \
67+ pthread_set_qos_class_self_np (qos, 0 );\
68+ Test* t; \
69+ B63_SUSPEND { \
70+ t = new Test (kSize , n); \
71+ } \
72+ int64_t res = t->run <unroll>(); \
73+ B63_KEEP (res); \
74+ B63_SUSPEND { \
75+ delete t; \
76+ }\
8677 }
8778
88- int64_t res = t->run ();
89-
90- B63_KEEP (res);
91- B63_SUSPEND {
92- delete t;
93- }
94- }
79+ #define FIRESTORM_UNROLLED (unroll ) BM_UNROLLED(firestorm, QOS_CLASS_USER_INTERACTIVE, unroll)
80+ #define ICESTORM_UNROLLED (unroll ) BM_UNROLLED(icestorm, QOS_CLASS_BACKGROUND, unroll)
9581
96- B63_BENCHMARK (icestorm_unrolled, n) {
97- pthread_set_qos_class_self_np (QOS_CLASS_BACKGROUND, 0 );
98- Test* t;
99- B63_SUSPEND {
100- t = new Test (kSize , n);
101- }
82+ FIRESTORM_UNROLLED (1 )
83+ FIRESTORM_UNROLLED(2 )
84+ FIRESTORM_UNROLLED(4 )
85+ FIRESTORM_UNROLLED(8 )
86+ FIRESTORM_UNROLLED(16 )
10287
103- int64_t res = t->run_unrolled ();
104-
105- B63_KEEP (res);
106- B63_SUSPEND {
107- delete t;
108- }
109- }
110-
111- B63_BASELINE (firestorm, n) {
112- pthread_set_qos_class_self_np (QOS_CLASS_USER_INTERACTIVE, 0 );
113- Test* t;
114- B63_SUSPEND {
115- t = new Test (kSize , n);
116- }
117-
118- int64_t res = t->run ();
119-
120- B63_KEEP (res);
121- B63_SUSPEND {
122- delete t;
123- }
124- }
125-
126- B63_BENCHMARK (firestorm_unrolled, n) {
127- pthread_set_qos_class_self_np (QOS_CLASS_USER_INTERACTIVE, 0 );
128- Test* t;
129- B63_SUSPEND {
130- t = new Test (kSize , n);
131- }
132-
133- int64_t res = t->run_unrolled ();
134-
135- B63_KEEP (res);
136- B63_SUSPEND {
137- delete t;
138- }
139- }
88+ ICESTORM_UNROLLED(1 )
89+ ICESTORM_UNROLLED(2 )
90+ ICESTORM_UNROLLED(4 )
91+ ICESTORM_UNROLLED(8 )
92+ ICESTORM_UNROLLED(16 )
14093
14194int main(int argc, char **argv) {
14295 srand (time (0 ));
0 commit comments