From: Peizhao Ou Date: Fri, 17 Jan 2014 22:16:40 +0000 (-0800) Subject: more X-Git-Url: http://plrg.eecs.uci.edu/git/?p=cdsspec-compiler.git;a=commitdiff_plain;h=b5590a7174ba510c646b9033c1df4951f9a1efae;hp=4f1e1f913bc95499f9e5fff2a8e30938b7cf3f08 more --- diff --git a/benchmark/cliffc-hashtable/cliffc_hashtable.h b/benchmark/cliffc-hashtable/cliffc_hashtable.h index 6edee89..49dc728 100644 --- a/benchmark/cliffc-hashtable/cliffc_hashtable.h +++ b/benchmark/cliffc-hashtable/cliffc_hashtable.h @@ -3,8 +3,8 @@ #include #include -#include -#include +#include +#include using namespace std; @@ -29,7 +29,7 @@ struct kvs_data { kvs_data(int sz) { _size = sz; - int real_size = sizeof(atomic) * 2 + 2; + int real_size = sz * 2 + 2; _data = new atomic[real_size]; // The control block should be initialized in resize() // Init the hash record array @@ -176,6 +176,7 @@ friend class CHM; } kvs_data* resize(cliffc_hashtable *topmap, kvs_data *kvs) { + //model_print("resizing...\n"); kvs_data *newkvs = _newkvs.load(memory_order_acquire); if (newkvs != NULL) return newkvs; @@ -203,7 +204,7 @@ friend class CHM; newkvs = new kvs_data(newsz); void *chm = (void*) new CHM(sz); - newkvs->_data[0].store(chm, memory_order_relaxed); + newkvs->_data[0].store(chm, memory_order_release); kvs_data *cur_newkvs; // Another check after the slow allocation @@ -223,7 +224,7 @@ friend class CHM; void help_copy_impl(cliffc_hashtable *topmap, kvs_data *oldkvs, bool copy_all) { - assert (get_chm(oldkvs) == this); + MODEL_ASSERT (get_chm(oldkvs) == this); kvs_data *newkvs = _newkvs.load(memory_order_acquire); int oldlen = oldkvs->_size; int min_copy_work = oldlen > 1024 ? 1024 : oldlen; @@ -328,7 +329,7 @@ friend class CHM; private: - static const int Default_Init_Size = 8; // Intial table size + static const int Default_Init_Size = 4; // Intial table size static slot* const MATCH_ANY; static slot* const NO_MATCH_OLD; @@ -379,7 +380,7 @@ friend class CHM; kvs_data *kvs = _kvs.load(memory_order_acquire); slot *V = get_impl(this, kvs, key_slot, fullhash); if (V == NULL) return NULL; - assert (!is_prime(V)); + MODEL_ASSERT (!is_prime(V)); return (TypeV*) V->_ptr; } @@ -499,7 +500,8 @@ friend class CHM; private: static CHM* get_chm(kvs_data* kvs) { - return (CHM*) kvs->_data[0].load(memory_order_relaxed); + CHM *res = (CHM*) kvs->_data[0].load(memory_order_relaxed); + return res; } static int* get_hashes(kvs_data *kvs) { @@ -508,10 +510,11 @@ friend class CHM; // Preserve happens-before semantics on newly inserted keys static inline slot* key(kvs_data *kvs, int idx) { - assert (idx >= 0 && idx < kvs->_size); + MODEL_ASSERT (idx >= 0 && idx < kvs->_size); // Corresponding to the volatile read in get_impl() and putIfMatch in // Cliff Click's Java implementation - return (slot*) kvs->_data[idx * 2 + 2].load(memory_order_acquire); + slot *res = (slot*) kvs->_data[idx * 2 + 2].load(memory_order_acquire); + return res; } /** @@ -524,7 +527,7 @@ friend class CHM; */ // Preserve happens-before semantics on newly inserted values static inline slot* val(kvs_data *kvs, int idx) { - assert (idx >= 0 && idx < kvs->_size); + MODEL_ASSERT (idx >= 0 && idx < kvs->_size); // Corresponding to the volatile read in get_impl() and putIfMatch in // Cliff Click's Java implementation slot *res = (slot*) kvs->_data[idx * 2 + 3].load(memory_order_acquire); @@ -542,7 +545,7 @@ friend class CHM; } static int hash(slot *key_slot) { - assert(key_slot != NULL && key_slot->_ptr != NULL); + MODEL_ASSERT(key_slot != NULL && key_slot->_ptr != NULL); TypeK* key = (TypeK*) key_slot->_ptr; int h = key->hashCode(); // Spread bits according to Cliff Click's code @@ -570,7 +573,7 @@ friend class CHM; static bool keyeq(slot *K, slot *key_slot, int *hashes, int hash, int fullhash) { // Caller should've checked this. - assert (K != NULL); + MODEL_ASSERT (K != NULL); TypeK* key_ptr = (TypeK*) key_slot->_ptr; return K == key_slot || @@ -580,7 +583,7 @@ friend class CHM; } static bool valeq(slot *val_slot1, slot *val_slot2) { - assert (val_slot1 != NULL); + MODEL_ASSERT (val_slot1 != NULL); TypeK* ptr1 = (TypeV*) val_slot1->_ptr; if (val_slot2 == NULL || ptr1 == NULL) return false; return ptr1->equals(val_slot2->_ptr); @@ -633,7 +636,7 @@ friend class CHM; @End */ - if (V == NULL) return NULL; // A miss + if (K == NULL) return NULL; // A miss if (keyeq(K, key_slot, hashes, idx, fullhash)) { // Key hit! Check if table-resize in progress @@ -685,8 +688,8 @@ friend class CHM; kvs_data *kvs = _kvs.load(memory_order_acquire); slot *res = putIfMatch(this, kvs, key_slot, value_slot, old_val); // Only when copy_slot() call putIfMatch() will it return NULL - assert (res != NULL); - assert (!is_prime(res)); + MODEL_ASSERT (res != NULL); + MODEL_ASSERT (!is_prime(res)); return res == TOMBSTONE ? NULL : (TypeV*) res->_ptr; } @@ -699,9 +702,9 @@ friend class CHM; */ static slot* putIfMatch(cliffc_hashtable *topmap, kvs_data *kvs, slot *key_slot, slot *val_slot, slot *expVal) { - assert (val_slot != NULL); - assert (!is_prime(val_slot)); - assert (!is_prime(expVal)); + MODEL_ASSERT (val_slot != NULL); + MODEL_ASSERT (!is_prime(val_slot)); + MODEL_ASSERT (!is_prime(expVal)); int fullhash = hash(key_slot); int len = kvs->_size; @@ -727,7 +730,7 @@ friend class CHM; break; } K = key(kvs, idx); // CAS failed, get updated value - assert (K != NULL); + MODEL_ASSERT (K != NULL); } // Key slot not null, there exists a Key here @@ -764,7 +767,7 @@ friend class CHM; // Decided to update the existing table while (true) { - assert (!is_prime(V)); + MODEL_ASSERT (!is_prime(V)); if (expVal != NO_MATCH_OLD && V != expVal && diff --git a/benchmark/cliffc-hashtable/main.cc b/benchmark/cliffc-hashtable/main.cc index 7641fc0..cadedce 100644 --- a/benchmark/cliffc-hashtable/main.cc +++ b/benchmark/cliffc-hashtable/main.cc @@ -45,33 +45,73 @@ class IntWrapper { } }; - -cliffc_hashtable table; -IntWrapper *val; +cliffc_hashtable *table; +IntWrapper *val1, *val2; void threadA(void *arg) { - IntWrapper k1(3), k2(4), v1(1), v2(2); - table.put(k1, v1); - table.put(k2, v2); + /* + IntWrapper k1(3), k2(5), k3(1024), k4(1025); + IntWrapper v1(1), v2(2), v3(73), v4(81); + table->put(k1, v1); + table->put(k2, v2); + val1 = table->get(k3); + table->put(k3, v3); + */ + for (int i = 200; i < 205; i++) { + IntWrapper k(i), v(i * 2); + table->put(k, v); + } } void threadB(void *arg) { - IntWrapper k1(3), k2(4), v1(1), v2(2); - val = table.get(k2); + IntWrapper k1(3), k2(5), k3(1024), k4(1025); + IntWrapper v1(1), v2(2), v3(73), v4(81); + table->put(k1, v3); + table->put(k2, v4); + val1 = table->get(k2); +} + +void threadC(void *arg) { + IntWrapper k1(3), k2(5), k3(1024), k4(1025); + IntWrapper v1(1), v2(2), v3(73), v4(81); + table->put(k1, v1); + table->put(k2, v2); + val2 = table->get(k1); +} + +void threadD(void *arg) { + IntWrapper k1(3), k2(5), k3(1024), k4(1025); + IntWrapper v1(1), v2(2), v3(73), v4(81); + table->put(k1, v2); + table->put(k2, v1); + val2 = table->get(k2); } int user_main(int argc, char *argv[]) { - thrd_t t1, t2; - val = new IntWrapper(0); + thrd_t t1, t2, t3, t4; + table = new cliffc_hashtable(); + val1 = NULL; + val2 = NULL; thrd_create(&t1, threadA, NULL); thrd_create(&t2, threadB, NULL); + thrd_create(&t3, threadC, NULL); + //thrd_create(&t4, threadD, NULL); thrd_join(t1); - thrd_join(t2);/* - if (val == NULL) { - cout << "NULL" << endl; + thrd_join(t2); + thrd_join(t3); + //thrd_join(t4); + + if (val1 == NULL) { + cout << "val1: NULL" << endl; + } else { + cout << val1->get() << endl; + } + MODEL_ASSERT(val1 == NULL || val1->get() == 2 || val1->get() == 81); + if (val2 == NULL) { + cout << "val2: NULL" << endl; } else { - cout << val->get() << endl; - }*/ + cout << val2->get() << endl; + } return 0; }