diff --git a/openmp/8-dotproduct-v0.cpp b/openmp/8-dotproduct-v0.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3388d9a2fabd7804f98df549db080de5a7aea959
--- /dev/null
+++ b/openmp/8-dotproduct-v0.cpp
@@ -0,0 +1,26 @@
+#include <omp.h>
+#define MAX_THREADS 128
+
+float dotproduct(float *x, int *y, int n)
+{
+  int i;
+  int nthreads = 0;
+  float d[MAX_THREADS];
+  float r;
+  #pragma omp parallel shared(x,y,d, nthreads), private(i), firstprivate(n)
+  {
+    #pragma omp master
+    nthreads = omp_get_num_threads();
+    
+    int tid = omp_get_thread_num();
+    d[tid]=0;
+    #pragma omp for
+    for (i=0; i<n; i++) {
+      d[tid] += x[i]*y[i];
+    }
+  }
+  for (i=0; i<nthreads; ++i)
+    r+=d[i];
+  return r;
+}
+
diff --git a/openmp/8-dotproduct-v1.cpp b/openmp/8-dotproduct-v1.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6e11d6bbf226f25b9f3cc260408d7afa2d83ae23
--- /dev/null
+++ b/openmp/8-dotproduct-v1.cpp
@@ -0,0 +1,11 @@
+float dotproduct(float *x, int *y, int n)
+{
+  int i;
+  float d;
+#pragma omp parallel for private(i) shared(x, y) firstprivate(n) \
+        reduction(+:d)
+  for (i=0; i<n; i++) {
+    d += x[i]*y[i];
+  }
+  return d;
+}