Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

PROJECT(test_trace)
# SET(CMAKE_CXX_FLAGS "-Wall -O3 -pthread -std=c++14")
SET(CMAKE_CXX_FLAGS " -Wl,--rpath=./lib/ -m64 -Wall -O3 -pthread -std=c++14 -fPIC")
SET(CMAKE_CXX_FLAGS " -Wl,--rpath=./lib/ -m64 -Wall -O3 -pthread -std=c++14 -fPIC -g")

SET(SRC_LIST test_trace.cpp)

Expand Down
29 changes: 19 additions & 10 deletions cache/FIFO_FH.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ class FIFO_FHCache : public FHCacheAPI<TKey, TValue, THash> {

// TODO @ Ziyue: clarify the difference between tier_ready and tier_no_insert
// and the duty of each variable
bool tier_ready = false;
// bool tier_ready = false;

private:
/**
Expand Down Expand Up @@ -256,6 +256,7 @@ class FIFO_FHCache : public FHCacheAPI<TKey, TValue, THash> {
bool fast_hash_ready = false;
bool fast_hash_construct = false;
std::atomic<bool> tier_no_insert{false};
std::atomic<bool> tier_ready{false};
std::atomic<bool> curve_flag{false};
std::atomic<size_t> movement_counter{0};
std::atomic<size_t> eviction_counter{0};
Expand Down Expand Up @@ -289,13 +290,14 @@ FIFO_FHCache<TKey, TValue, THash>::FIFO_FHCache(size_t maxSize)
int align_len = 1 + int(log2(m_maxSize));
m_fasthash.reset(new FastHash::CLHT<TValue>(0, align_len));
//m_fasthash.reset(new FastHash::TbbCHT<TValue>(m_maxSize));
// printf("hiiiii\n");
}

template <class TKey, class TValue, class THash>
bool FIFO_FHCache<TKey, TValue, THash>::construct_ratio(double FC_ratio) {
// Check valid ratio
assert(FC_ratio <= 1 && FC_ratio >=0);

printf("check FC Ratio: %f\n", FC_ratio);
// Check that Frozen LinkedList is empty (previously in DC mode)
assert(m_fast_head.m_next == &m_fast_tail);
assert(m_fast_tail.m_prev == &m_fast_head);
Expand Down Expand Up @@ -390,7 +392,7 @@ bool FIFO_FHCache<TKey, TValue, THash>::construct_ratio(double FC_ratio) {
printf("fast hash insert num: %lu, fail count: %lu, m_size: %ld (FC_ratio: %.2lf)\n",
count, fail_count, m_size.load(), count*1.0/m_size.load());
else
printf("fast hash insert num: %lu, m_size: %ld (FC_ratio: %.2lf)\n",
printf("Construct_ratio fast hash insert num: %lu, m_size: %ld (FC_ratio: %.2lf)\n",
count, m_size.load(), count*1.0/m_size.load());


Expand All @@ -406,7 +408,10 @@ bool FIFO_FHCache<TKey, TValue, THash>::construct_tier() {
// Lock the whole list
std::unique_lock<ListMutex> lock(m_listMutex);

assert(tier_ready.load() == tier_no_insert.load());

fast_hash_construct = true;
tier_ready = true;
tier_no_insert = true; // reject insert

// Check Frozen part was empty
Expand Down Expand Up @@ -477,7 +482,7 @@ bool FIFO_FHCache<TKey, TValue, THash>::construct_tier() {
temp_node = temp_node->m_next;
}

printf("fast hash insert num: %d, m_size: %ld (FC_ratio: %.2lf)\n",
printf("construct_tier fast hash insert num: %d, m_size: %ld (FC_ratio: %.2lf)\n",
count, m_size.load(), count*1.0/m_size.load());
tier_ready = true;
fast_hash_construct = false;
Expand Down Expand Up @@ -594,9 +599,9 @@ bool FIFO_FHCache<TKey, TValue, THash>::find(TValue& ac,
return true;
}
else { // Not found in frozen
if(tier_ready){ // If we only have frozen, then cache miss anyway
if(tier_ready && is_full()){ // If we only have frozen, then cache miss anyway // and DC size==0
#ifdef FH_STAT
if(stat_yes) {
if(stat_yes) {
FIFO_FHCache::tbb_find_miss++;
}
#endif
Expand Down Expand Up @@ -679,9 +684,10 @@ bool FIFO_FHCache<TKey, TValue, THash>::find(TValue& ac,
// Record the FC ratio, and the FC hit, DC hit, (DC) miss by filling the curve container
template <class TKey, class TValue, class THash>
bool FIFO_FHCache<TKey, TValue, THash>::get_curve(bool& should_stop) {
assert(!tier_no_insert.load()); // Shouldn't call get curve (learning state)
// assert(!tier_no_insert.load()); // Shouldn't call get curve (learning state)
// when flag indicates the whole cache is frozen (frozen state)

assert(!tier_ready.load());
assert(tier_ready.load() == tier_no_insert.load());
// Create a marker and insert to the list
m_marker = new ListNode(MARKER_KEY);
size_t pass_counter = 0;
Expand Down Expand Up @@ -767,7 +773,9 @@ bool FIFO_FHCache<TKey, TValue, THash>::insert(const TKey& key,

// Insert into the CHM
// Basically if the whole cache is frozen, you can do nothing
if(tier_no_insert.load())
// if(tier_no_insert.load() && is_full())
assert(tier_ready.load() == tier_no_insert.load());
if(tier_ready.load() && is_full())
return false;

// Generate some variables for insertion
Expand Down Expand Up @@ -801,7 +809,8 @@ bool FIFO_FHCache<TKey, TValue, THash>::insert(const TKey& key,
// exist.
std::unique_lock<ListMutex> lock(m_listMutex);
// Frozen all cahce
if(tier_no_insert.load()){
// if(tier_no_insert.load()){
if(tier_ready.load()){
// How can we still reach this point:
// while we are inserting, the cache is 100% frozen
lock.unlock();
Expand Down
206 changes: 104 additions & 102 deletions cache/hhvm-scalable-cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,9 @@ ConcurrentScalableCache<TKey, TValue, THash>::
getShard(const TKey& key) {
THash hashObj;
constexpr int shift = std::numeric_limits<size_t>::digits - 16;
size_t h = (hashObj.hash(key) >> shift) % m_numShards;
// printf("check num_shards: %d\n", m_numShards);
size_t h = (hashObj.hash(key)) % m_numShards;
// printf("check shard index %d, key: %d,shift: %d, x: %d\n", h, key, shift, (hashObj.hash(key) >> shift));
// size_t h = key % m_numShards;
// std::cout << "before hash: " << hashObj.hash(key) << std::endl;
// std::cout << "hashed at shard: " << h << std::endl;
Expand Down Expand Up @@ -657,115 +659,115 @@ FastHashMonitor(){
printf("\n* end observation *\n");

printf("\n* start search *\n");
auto start_learning_time = SSDLOGGING_TIME_NOW;

// get curve
if(!should_stop) // get FC hit, DC hit, DC miss each FC_ratio
m_shards[0]->get_curve(should_stop);

// calculate optimal FC_ratio
auto container = m_shards[0]->curve_container;
double best_avg = 1000, best_size = 0;
double DC_hit_lat = 0, miss_lat = 0, FC_lat = 0;
double disk_lat = 0;
double Frozen_Avg = 0, Frozen_Miss = 0, best_option_tMiss = 0;

/* observe baseline for a while */
do{
usleep(WAIT_STABLE_SLEEP_INTERVAL_US);
}while(total_other_latency_.size_from_last_end() < 5 && !should_stop);
printf("\ndraw curve\ndata pass %lu\n", print_step_counter++);
PrintMissRatio();
/* become aware of DC latency (hit lat) and DC miss latency + disk latency (miss lat) */
PrintStepLat(DC_hit_lat, miss_lat);

// first do 100% FC
for(size_t i = 0; i < m_numShards; i++){
m_shards[i]->construct_tier();
}
printf("\ndata pass %lu\n", print_step_counter++);
PrintMissRatio();
PrintStepLat();

/* Controller "sleep" for a while
* the cache runs in 100% FH,
* get performance and miss ratio after sleep
*/
usleep(WAIT_STABLE_SLEEP_INTERVAL_US);
printf("\ndata pass %lu\n", print_step_counter++);
// auto start_learning_time = SSDLOGGING_TIME_NOW;

// // get curve
// if(!should_stop) // get FC hit, DC hit, DC miss each FC_ratio
// m_shards[0]->get_curve(should_stop);

// // calculate optimal FC_ratio
// auto container = m_shards[0]->curve_container;
// double best_avg = 1000, best_size = 0;
// double DC_hit_lat = 0, miss_lat = 0, FC_lat = 0;
// double disk_lat = 0;
// double Frozen_Avg = 0, Frozen_Miss = 0, best_option_tMiss = 0;

// /* observe baseline for a while */
// do{
// usleep(WAIT_STABLE_SLEEP_INTERVAL_US);
// }while(total_other_latency_.size_from_last_end() < 5 && !should_stop);
// printf("\ndraw curve\ndata pass %lu\n", print_step_counter++);
// PrintMissRatio();
// /* become aware of DC latency (hit lat) and DC miss latency + disk latency (miss lat) */
// PrintStepLat(DC_hit_lat, miss_lat);

// // first do 100% FC
// for(size_t i = 0; i < m_numShards; i++){
// m_shards[i]->construct_tier();
// }
// printf("\ndata pass %lu\n", print_step_counter++);
// PrintMissRatio();
// PrintStepLat();

// /* Controller "sleep" for a while
// * the cache runs in 100% FH,
// * get performance and miss ratio after sleep
// */
// usleep(WAIT_STABLE_SLEEP_INTERVAL_US);
// printf("\ndata pass %lu\n", print_step_counter++);

/* get one endpoint of FC miss ratio in curve -- when 100% FC
* but not used (only printed)
*/
Frozen_Miss = PrintMissRatio();
/* become aware of FC latency (hit lat) and disk latency (miss lat) */
Frozen_Avg = PrintStepLat(FC_lat, disk_lat);
for(size_t i = 0; i < m_numShards; i++){
m_shards[i]->deconstruct();
}

printf("\nHothash lat: %.3lf, 100%% Frozen Avg lat: %.3lf us, Miss Rate: %.3lf\n",
FC_lat, Frozen_Avg, Frozen_Miss);
fflush(stdout);

// in-cache hit miss is only lookup pass metrics, e.g. 99% hit
// for client, hit may be 50%, miss ~0.5%, then 49.5% write (i.e. insert)
// better add a counter for insert()

// Calculate the best FC ratio for shard 0, but will be applied to all shards
for(size_t i = 0; i < container.size(); i++){
auto tSize = container[i].size_;
auto tFC_hit_ = container[i].FC_hit_;
auto tMiss = container[i].miss_;
double avg;
if(tSize < 0.01){
avg = tMiss * miss_lat + (1-tMiss) * DC_hit_lat;
tSize = 0;
printf("when baseline, avg from %.3lf to %.3lf\n",
avg, avg / (1 + FH_PERFORMANCE_THRESHOLD));
avg = avg / (1 + FH_PERFORMANCE_THRESHOLD);
}
// /* get one endpoint of FC miss ratio in curve -- when 100% FC
// * but not used (only printed)
// */
// Frozen_Miss = PrintMissRatio();
// /* become aware of FC latency (hit lat) and disk latency (miss lat) */
// Frozen_Avg = PrintStepLat(FC_lat, disk_lat);
// for(size_t i = 0; i < m_numShards; i++){
// m_shards[i]->deconstruct();
// }

// when tSize is large, we regard it as ~100% FC
else if(i == container.size() - 1 && tSize > 0.65){
//avg = tMiss * disk_lat + (1-tMiss) * FC_lat;
printf("regard tSize from %.3lf to %d\n", tSize, 1);
tSize = 1;
avg = tFC_hit_ * FC_lat + tMiss * (miss_lat+FC_lat) + (1-tFC_hit_-tMiss) * (FC_lat + DC_hit_lat);
}
else {
avg = tFC_hit_ * FC_lat + tMiss * (miss_lat+FC_lat) + (1-tFC_hit_-tMiss) * (FC_lat + DC_hit_lat);
}
// printf("\nHothash lat: %.3lf, 100%% Frozen Avg lat: %.3lf us, Miss Rate: %.3lf\n",
// FC_lat, Frozen_Avg, Frozen_Miss);
// fflush(stdout);

if(avg < best_avg){
best_avg = avg;
best_size = tSize;
best_option_tMiss = tMiss;
/* only print when best avg is updated */
printf("(Update) best avg: %.3lf us, best size: %.3lf (w. FC_hit: %.3lf, miss: %.3lf)\n",
best_avg, best_size, tFC_hit_, best_option_tMiss);
}
}
// // in-cache hit miss is only lookup pass metrics, e.g. 99% hit
// // for client, hit may be 50%, miss ~0.5%, then 49.5% write (i.e. insert)
// // better add a counter for insert()

// // Calculate the best FC ratio for shard 0, but will be applied to all shards
// for(size_t i = 0; i < container.size(); i++){
// auto tSize = container[i].size_;
// auto tFC_hit_ = container[i].FC_hit_;
// auto tMiss = container[i].miss_;
// double avg;
// if(tSize < 0.01){
// avg = tMiss * miss_lat + (1-tMiss) * DC_hit_lat;
// tSize = 0;
// printf("when baseline, avg from %.3lf to %.3lf\n",
// avg, avg / (1 + FH_PERFORMANCE_THRESHOLD));
// avg = avg / (1 + FH_PERFORMANCE_THRESHOLD);
// }

// // when tSize is large, we regard it as ~100% FC
// else if(i == container.size() - 1 && tSize > 0.65){
// //avg = tMiss * disk_lat + (1-tMiss) * FC_lat;
// printf("regard tSize from %.3lf to %d\n", tSize, 1);
// tSize = 1;
// avg = tFC_hit_ * FC_lat + tMiss * (miss_lat+FC_lat) + (1-tFC_hit_-tMiss) * (FC_lat + DC_hit_lat);
// }
// else {
// avg = tFC_hit_ * FC_lat + tMiss * (miss_lat+FC_lat) + (1-tFC_hit_-tMiss) * (FC_lat + DC_hit_lat);
// }

// if(avg < best_avg){
// best_avg = avg;
// best_size = tSize;
// best_option_tMiss = tMiss;
// /* only print when best avg is updated */
// printf("(Update) best avg: %.3lf us, best size: %.3lf (w. FC_hit: %.3lf, miss: %.3lf)\n",
// best_avg, best_size, tFC_hit_, best_option_tMiss);
// }
// }

// Compare best "partially" frozen [0, 100%) one with 100% Frozen
if(best_avg > Frozen_Avg){
printf("(Update) best avg: %.3lf us, best size: %.3lf\n",
Frozen_Avg, 1.0);
best_avg = Frozen_Avg;
best_size = 1.0;
}
// // Compare best "partially" frozen [0, 100%) one with 100% Frozen
// if(best_avg > Frozen_Avg){
// printf("(Update) best avg: %.3lf us, best size: %.3lf\n",
// Frozen_Avg, 1.0);
// best_avg = Frozen_Avg;
// best_size = 1.0;
// }

// clear curve container
// Only using shard 0 for profiling
m_shards[0]->curve_container.clear();
// // clear curve container
// // Only using shard 0 for profiling
// m_shards[0]->curve_container.clear();

auto learning_duration = SSDLOGGING_TIME_DURATION(start_learning_time, SSDLOGGING_TIME_NOW);
printf("\nsearch time: %lf s\n", learning_duration / 1000 / 1000);
printf("Profiling best size: %.3lf\n", best_size);
// auto learning_duration = SSDLOGGING_TIME_DURATION(start_learning_time, SSDLOGGING_TIME_NOW);
// printf("\nsearch time: %lf s\n", learning_duration / 1000 / 1000);
// printf("Profiling best size: %.3lf\n", best_size);

// debugging
// printf("\nDebug: Test 1.0 Size\n");
// best_size = 1;
printf("\nDebug: Test 1.0 Size\n");
double best_size = 1;

// End of FH evaluation, and got the desired ratio to construct
printf("\n* end search *\n");
Expand Down
Loading