lib: Add prefetch support (for GCC)
authorJarno Rajahalme <jrajahalme@nicira.com>
Tue, 29 Apr 2014 22:50:38 +0000 (15:50 -0700)
committerJarno Rajahalme <jrajahalme@nicira.com>
Tue, 29 Apr 2014 22:50:38 +0000 (15:50 -0700)
Define OVS_PREFETCH() and OVS_PREFETCH_WRITE() using builtin prefetch
for GCC, and ovs_prefetch_range() for prefetching a range of addresses.

Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com>
Acked-by: Ethan Jackson <ethan@nicira.com>
lib/compiler.h
lib/util.h

index 3b59813..cfe9066 100644 (file)
     static void f(void)
 #endif
 
+/* OVS_PREFETCH() can be used to instruct the CPU to fetch the cache
+ * line containing the given address to a CPU cache.
+ * OVS_PREFETCH_WRITE() should be used when the memory is going to be
+ * written to.  Depending on the target CPU, this can generate the same
+ * instruction as OVS_PREFETCH(), or bring the data into the cache in an
+ * exclusive state. */
+#if __GNUC__
+#define OVS_PREFETCH(addr) __builtin_prefetch((addr))
+#define OVS_PREFETCH_WRITE(addr) __builtin_prefetch((addr), 1)
+#else
+#define OVS_PREFETCH(addr)
+#define OVS_PREFETCH_WRITE(addr)
+#endif
+
 #endif /* compiler.h */
index bff6153..743b9fe 100644 (file)
@@ -151,6 +151,19 @@ is_pow2(uintmax_t x)
 #define CACHE_LINE_SIZE 64
 BUILD_ASSERT_DECL(IS_POW2(CACHE_LINE_SIZE));
 
+#define CACHE_LINE_SIZE 64      /* Correct for most CPUs. */
+
+static inline void
+ovs_prefetch_range(const void *start, size_t size)
+{
+    const char *addr = (const char *)start;
+    size_t ofs;
+
+    for (ofs = 0; ofs < size; ofs += CACHE_LINE_SIZE) {
+        OVS_PREFETCH(addr + ofs);
+    }
+}
+
 #ifndef MIN
 #define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
 #endif
@@ -486,6 +499,7 @@ uint64_t bitwise_get(const void *src, unsigned int src_len,
                      unsigned int src_ofs, unsigned int n_bits);
 
 void xsleep(unsigned int seconds);
+
 #ifdef _WIN32
 \f
 char *ovs_format_message(int error);