changes to hashmap
authorPeizhao Ou <peizhaoo@uci.edu>
Tue, 17 Feb 2015 20:12:57 +0000 (12:12 -0800)
committerPeizhao Ou <peizhaoo@uci.edu>
Tue, 17 Feb 2015 20:12:57 +0000 (12:12 -0800)
concurrent-hashmap/Makefile
concurrent-hashmap/hashmap.h
concurrent-hashmap/hashmap_wildcard.h
concurrent-hashmap/main.cc [new file with mode: 0644]
concurrent-hashmap/result1.txt [new file with mode: 0644]
concurrent-hashmap/result2.txt [new file with mode: 0644]
concurrent-hashmap/testcase3.cc [new file with mode: 0644]

index fece808a6d7610afe63eedc31c9232e0650ad1ab..89e5244b22dc7dfdafd062823ef34e595d88fe4a 100644 (file)
@@ -1,7 +1,7 @@
 include ../benchmarks.mk
 
 BENCH := hashmap
-NORMAL_TESTS := testcase1 testcase2
+NORMAL_TESTS := testcase1 testcase2 testcase3
 
 WILDCARD_TESTS := $(patsubst %, %_wildcard, $(NORMAL_TESTS))
 
index 8e6f196cb0e8c73d8a02f9dee01b152dddea7cc9..0d249251ec99dcaabbd10d301df8873a5f3a9cc1 100644 (file)
@@ -165,10 +165,9 @@ class HashMap {
                // lock, we ignore this operation for the SC analysis, and otherwise we
                // take it into consideration
                
-               //SC_BEGIN();
+               SC_BEGIN();
                Entry *firstPtr = first->load(acquire);
-               //SC_KEEP();
-               //SC_END();
+               SC_END();
 
                e = firstPtr;
                while (e != NULL) {
@@ -179,8 +178,9 @@ class HashMap {
                                else
                                        break;
                        }
-                       // Loading the next entry
-                       e = e->next.load(acquire);
+                       // Loading the next entry, this can be relaxed because the
+                       // synchronization has been established by the load of head
+                       e = e->next.load(relaxed);
                }
        
                // Recheck under synch if key apparently not there or interference
@@ -194,7 +194,8 @@ class HashMap {
                        e = newFirstPtr;
                        while (e != NULL) {
                                if (e->hash == hash && eq(key, e->key)) {
-                                       res = e->value.load(seq_cst);
+                                       // Protected by lock, no need to be SC
+                                       res = e->value.load(relaxed);
                                        seg->unlock(); // Critical region ends
                                        return res;
                                }
@@ -228,8 +229,8 @@ class HashMap {
                while (e != NULL) {
                        if (e->hash == hash && eq(key, e->key)) {
                                // FIXME: This could be a relaxed (because locking synchronize
-                               // with the previous put())?? 
-                               oldValue = e->value.load(acquire);
+                               // with the previous put())??  no need to be acquire
+                               oldValue = e->value.load(relaxed);
                                e->value.store(value, seq_cst);
                                seg->unlock(); // Don't forget to unlock before return
                                return oldValue;
@@ -276,8 +277,8 @@ class HashMap {
                }
 
                // FIXME: This could be a relaxed (because locking synchronize
-               // with the previous put())?? 
-               oldValue = e->value.load(acquire);
+               // with the previous put())?? No need to be acquire
+               oldValue = e->value.load(relaxed);
                // If the value parameter is NULL, we will remove the entry anyway
                if (value != NULL && value->equals(oldValue)) {
                        seg->unlock();
index 0713b782c9288d7101bf7de8427c2ae22a91333d..6ad59db15e40a4644645359b217ce48a5c9331ad 100644 (file)
@@ -167,7 +167,6 @@ class HashMap {
                
                SC_BEGIN();
                Entry *firstPtr = first->load(wildcard(3)); // acquire
-               SC_KEEP();
                SC_END();
 
                e = firstPtr;
@@ -180,7 +179,7 @@ class HashMap {
                                        break;
                        }
                        // Loading the next entry
-                       e = e->next.load(wildcard(5)); // acquire
+                       e = e->next.load(wildcard(5)); // relaxed 
                }
        
                // Recheck under synch if key apparently not there or interference
@@ -194,7 +193,7 @@ class HashMap {
                        e = newFirstPtr;
                        while (e != NULL) {
                                if (e->hash == hash && eq(key, e->key)) {
-                                       res = e->value.load(wildcard(7)); // seq_cst
+                                       res = e->value.load(wildcard(7)); // relaxed
                                        seg->unlock(); // Critical region ends
                                        return res;
                                }
@@ -229,7 +228,7 @@ class HashMap {
                        if (e->hash == hash && eq(key, e->key)) {
                                // FIXME: This could be a relaxed (because locking synchronize
                                // with the previous put())?? 
-                               oldValue = e->value.load(wildcard(10)); // acquire
+                               oldValue = e->value.load(wildcard(10)); // relaxed 
                                e->value.store(value, wildcard(11)); // seq_cst
                                seg->unlock(); // Don't forget to unlock before return
                                return oldValue;
@@ -277,7 +276,7 @@ class HashMap {
 
                // FIXME: This could be a relaxed (because locking synchronize
                // with the previous put())?? 
-               oldValue = e->value.load(acquire);
+               oldValue = e->value.load(relaxed);
                // If the value parameter is NULL, we will remove the entry anyway
                if (value != NULL && value->equals(oldValue)) {
                        seg->unlock();
diff --git a/concurrent-hashmap/main.cc b/concurrent-hashmap/main.cc
new file mode 100644 (file)
index 0000000..084230e
--- /dev/null
@@ -0,0 +1,75 @@
+#include <iostream>
+#include <threads.h>
+#include "hashmap.h"
+
+HashMap *table;
+
+
+void printKey(Key *key) {
+       if (key)
+               printf("pos = (%d, %d, %d)\n", key->x, key->y, key->z);
+       else
+               printf("pos = NULL\n");
+}
+
+void printValue(Value *value) {
+       if (value)
+               printf("velocity = (%d, %d, %d)\n", value->vX, value->vY, value->vZ);
+       else
+               printf("velocity = NULL\n");
+}
+
+// Key(3, 2, 6) & Key(1, 3, 3) are hashed to the same slot -> 4
+// Key(1, 1, 1) & Key(3, 2, 2) are hashed to the same slot -> 0
+// Key(2, 4, 1) & Key(3, 4, 2) are hashed to the same slot -> 3
+// Key(3, 4, 5) & Key(1, 4, 3) are hashed to the same slot -> 5
+
+
+void threadA(void *arg) {
+       Key *k1 = new Key(3, 2, 6);
+       Key *k2 = new Key(1, 1, 1);
+       Value *v1 = new Value(10, 10, 10);
+       Value *r1 = table->put(k1, v1);
+       //printValue(r1);
+       Value *r2 = table->get(k2);
+       //printf("Thrd A:\n");
+       printValue(r2);
+}
+
+void threadB(void *arg) {
+       Key *k1 = new Key(3, 2, 6);
+       Key *k2 = new Key(1, 1, 1);
+       Value *v2 = new Value(30, 40, 50);
+       Value *r3 = table->put(k2, v2);
+       //printValue(r3);
+       Value *r4 = table->get(k1);
+       printf("Thrd B:\n");
+       printValue(r4);
+}
+
+int user_main(int argc, char *argv[]) {
+       thrd_t t1, t2;
+
+       Key *k1 = new Key(1, 3, 3);
+       Key *k1_prime = new Key(3, 2, 6);
+       Key *k2 = new Key(3, 2, 2);
+       Key *k2_prime = new Key(1, 1, 1);
+       Value *v1 = new Value(111, 111, 111);
+       Value *v2 = new Value(222, 222, 222);
+
+       table = new HashMap;
+
+       printf("Key1: %d\n", table->hashKey(k1) % table->capacity);
+       printf("Key1': %d\n", table->hashKey(k1_prime) % table->capacity);
+       printf("Key2: %d\n", table->hashKey(k2) % table->capacity);
+       printf("Key2': %d\n", table->hashKey(k2_prime) % table->capacity);
+
+       thrd_create(&t1, threadA, NULL);
+       thrd_create(&t2, threadB, NULL);
+       thrd_join(t1);
+       thrd_join(t2);
+       
+       return 0;
+}
+
+
diff --git a/concurrent-hashmap/result1.txt b/concurrent-hashmap/result1.txt
new file mode 100644 (file)
index 0000000..2425b57
--- /dev/null
@@ -0,0 +1,9 @@
+Result 0:
+wildcard 1 -> memory_order_relaxed
+wildcard 2 -> memory_order_relaxed
+wildcard 3 -> memory_order_acquire
+wildcard 4 -> memory_order_relaxed
+wildcard 6 -> memory_order_relaxed
+wildcard 7 -> memory_order_relaxed
+wildcard 9 -> memory_order_relaxed
+wildcard 13 -> memory_order_release
diff --git a/concurrent-hashmap/result2.txt b/concurrent-hashmap/result2.txt
new file mode 100644 (file)
index 0000000..c09db09
--- /dev/null
@@ -0,0 +1,11 @@
+Result 0:
+wildcard 1 -> memory_order_relaxed
+wildcard 2 -> memory_order_relaxed
+wildcard 3 -> memory_order_acquire
+wildcard 4 -> memory_order_seq_cst
+wildcard 6 -> memory_order_relaxed
+wildcard 7 -> memory_order_relaxed
+wildcard 9 -> memory_order_relaxed
+wildcard 10 -> memory_order_relaxed
+wildcard 11 -> memory_order_seq_cst
+wildcard 13 -> memory_order_release
diff --git a/concurrent-hashmap/testcase3.cc b/concurrent-hashmap/testcase3.cc
new file mode 100644 (file)
index 0000000..5b54a16
--- /dev/null
@@ -0,0 +1,81 @@
+#include <threads.h>
+
+#ifdef WILDCARD
+#include "hashmap_wildcard.h"
+#else
+#include "hashmap.h"
+#endif
+
+HashMap *table;
+
+void printKey(Key *key) {
+       if (key)
+               printf("pos = (%d, %d, %d)\n", key->x, key->y, key->z);
+       else
+               printf("pos = NULL\n");
+}
+
+void printValue(Value *value) {
+       if (value)
+               printf("velocity = (%d, %d, %d)\n", value->vX, value->vY, value->vZ);
+       else
+               printf("velocity = NULL\n");
+}
+
+// Key(3, 2, 6) & Key(1, 3, 3) are hashed to the same slot -> 4
+// Key(1, 1, 1) & Key(3, 2, 2) are hashed to the same slot -> 0
+// Key(2, 4, 1) & Key(3, 4, 2) are hashed to the same slot -> 3
+// Key(3, 4, 5) & Key(1, 4, 3) & Key(1, 1, 6) are hashed to the same slot -> 5
+// Key(2, 4, 8) & Key(1, 3, 8) -> 9
+// Key(1, 4, 8) -> 10
+// Key(1, 3, 7) -> 8
+// Key(1, 2, 7) -> 7
+// Key(1, 2, 6) -> 6
+
+void threadA(void *arg) {
+       Key *k1 = new Key(3, 4, 5);
+       Key *k2 = new Key(1, 4, 3);
+       Key *k3 = new Key(1, 1, 6);
+       Value *v2 = new Value(10, 10, 10);
+       Value *r1 = table->put(k2, v2);
+       //printValue(r1);
+       Value *r2 = table->get(k3);
+       printf("k1 -> %d:\n", table->hashKey(k1) % table->capacity);
+       printf("k2 -> %d:\n", table->hashKey(k2) % table->capacity);
+       printf("k3 -> %d:\n", table->hashKey(k3) % table->capacity);
+       //printValue(r2);
+}
+
+void threadB(void *arg) {
+       Key *k1 = new Key(3, 4, 5);
+       Key *k2 = new Key(1, 4, 3);
+       Key *k3 = new Key(1, 1, 6);
+       Value *v3 = new Value(30, 40, 50);
+       Value *r3 = table->put(k3, v3);
+       //printValue(r3);
+       //Value *r4 = table->get(k1);
+       //printf("Thrd B:\n");
+       //printValue(r4);
+}
+
+int user_main(int argc, char *argv[]) {
+       Key *k1 = new Key(3, 4, 5);
+       Key *k2 = new Key(1, 4, 3);
+       Key *k3 = new Key(1, 1, 6);
+       //Key *k2 = new Key(1, 3, 3);
+       Value *v1 = new Value(111, 111, 111);
+       //Value *v2 = new Value(222, 222, 222);
+       thrd_t t1, t2;
+       table = new HashMap;
+       table->put(k1, v1);
+       //table->put(k2, v2);
+
+       thrd_create(&t1, threadA, NULL);
+       thrd_create(&t2, threadB, NULL);
+       thrd_join(t1);
+       thrd_join(t2);
+       
+       return 0;
+}
+
+