forked from apache/brpc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
bvar_agent_group_unittest.cpp
139 lines (123 loc) · 4.34 KB
/
bvar_agent_group_unittest.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// Copyright (c) 2014 Baidu, Inc.
// Author Zhangyi Chen ([email protected])
// Date 2014/09/26 12:43:49
#include <pthread.h> // pthread_*
#include <cstddef>
#include <memory>
#include <iostream>
#include "butil/time.h"
#include "butil/macros.h"
#include "bvar/detail/agent_group.h"
#include "butil/atomicops.h"
#include <gtest/gtest.h>
namespace {
using namespace bvar::detail;
struct Add {
uint64_t operator()(const uint64_t lhs, const uint64_t rhs) const {
return lhs + rhs;
}
};
const size_t OPS_PER_THREAD = 2000000;
class AgentGroupTest : public testing::Test {
protected:
typedef butil::atomic<uint64_t> agent_type;
void SetUp() {}
void TearDown() {}
static void *thread_counter(void *arg) {
int id = (int)((long)arg);
agent_type *item = AgentGroup<agent_type>::get_or_create_tls_agent(id);
if (item == NULL) {
EXPECT_TRUE(false);
return NULL;
}
butil::Timer timer;
timer.start();
for (size_t i = 0; i < OPS_PER_THREAD; ++i) {
agent_type *element = AgentGroup<agent_type>::get_or_create_tls_agent(id);
uint64_t old_value = element->load(butil::memory_order_relaxed);
uint64_t new_value;
do {
new_value = old_value + 2;
} while (__builtin_expect(!element->compare_exchange_weak(old_value, new_value,
butil::memory_order_relaxed,
butil::memory_order_relaxed), 0));
//element->store(element->load(butil::memory_order_relaxed) + 2,
// butil::memory_order_relaxed);
//element->fetch_add(2, butil::memory_order_relaxed);
}
timer.stop();
return (void *)(timer.n_elapsed());
}
};
TEST_F(AgentGroupTest, test_sanity) {
int id = AgentGroup<agent_type>::create_new_agent();
ASSERT_TRUE(id >= 0) << id;
agent_type *element = AgentGroup<agent_type>::get_or_create_tls_agent(id);
ASSERT_TRUE(element != NULL);
AgentGroup<agent_type>::destroy_agent(id);
}
butil::atomic<uint64_t> g_counter(0);
void *global_add(void *) {
butil::Timer timer;
timer.start();
for (size_t i = 0; i < OPS_PER_THREAD; ++i) {
g_counter.fetch_add(2, butil::memory_order_relaxed);
}
timer.stop();
return (void *)(timer.n_elapsed());
}
TEST_F(AgentGroupTest, test_perf) {
size_t loops = 100000;
size_t id_num = 512;
int ids[id_num];
for (size_t i = 0; i < id_num; ++i) {
ids[i] = AgentGroup<agent_type>::create_new_agent();
ASSERT_TRUE(ids[i] >= 0);
}
butil::Timer timer;
timer.start();
for (size_t i = 0; i < loops; ++i) {
for (size_t j = 0; j < id_num; ++j) {
agent_type *agent =
AgentGroup<agent_type>::get_or_create_tls_agent(ids[j]);
ASSERT_TRUE(agent != NULL) << ids[j];
}
}
timer.stop();
LOG(INFO) << "It takes " << timer.n_elapsed() / (loops * id_num)
<< " ns to get tls agent for " << id_num << " agents";
for (size_t i = 0; i < id_num; ++i) {
AgentGroup<agent_type>::destroy_agent(ids[i]);
}
}
TEST_F(AgentGroupTest, test_all_perf) {
long id = AgentGroup<agent_type>::create_new_agent();
ASSERT_TRUE(id >= 0) << id;
pthread_t threads[24];
for (size_t i = 0; i < ARRAY_SIZE(threads); ++i) {
pthread_create(&threads[i], NULL, &thread_counter, (void *)id);
}
long totol_time = 0;
for (size_t i = 0; i < ARRAY_SIZE(threads); ++i) {
void *ret;
pthread_join(threads[i], &ret);
totol_time += (long)ret;
}
LOG(INFO) << "ThreadAgent takes "
<< totol_time / (OPS_PER_THREAD * ARRAY_SIZE(threads));
totol_time = 0;
g_counter.store(0, butil::memory_order_relaxed);
for (size_t i = 0; i < ARRAY_SIZE(threads); ++i) {
pthread_create(&threads[i], NULL, global_add, (void *)id);
}
for (size_t i = 0; i < ARRAY_SIZE(threads); ++i) {
void *ret;
pthread_join(threads[i], &ret);
totol_time += (long)ret;
}
LOG(INFO) << "Global Atomic takes "
<< totol_time / (OPS_PER_THREAD * ARRAY_SIZE(threads));
AgentGroup<agent_type>::destroy_agent(id);
//sleep(1000);
}
} // namespace