Re: [Mesa-dev] [PATCH] clover: Cache serialized binaries

2014-06-16 Thread Tom Stellard
On Sun, Jun 15, 2014 at 01:08:14PM +0200, Francisco Jerez wrote:
> Tom Stellard  writes:
> 
> > We were serializing the binaries once when clGetProgramInfo was called
> > with CL_PROGRAM_BINARY_SIZES and then again when it was called with
> > CL_PROGRAM_BINARIES.  This was slowing down some OpenCV tests which were
> > building binary kernel caches.
> >
> > This improves the run-time of OpenCV's OCL_ImgProc/CvtColor8u.*
> > test from 7 minutes to 1 minute.
> > ---
> 
> Can you give the attached two patches a try?  I'm curious to see if they
> have a comparable effect -- If they do I'd prefer to fix the underlying
> object rather than caching binaries in serialized form.
> 
> Thanks.
> 
> >[...]
> 

These patches improve performance even more.  Now it only takes 10 seconds to
run the tests instead of 7 minutes.

For both patches:

Tested-by: Tom Stellard 

> From a500126213b073793184b0b6f170a58229340778 Mon Sep 17 00:00:00 2001
> From: Francisco Jerez 
> Date: Sat, 14 Jun 2014 20:53:35 +0200
> Subject: [PATCH 1/2] clover: Optimize module serialization for vectors of
>  fundamental types.
> 
> ---
>  src/gallium/state_trackers/clover/core/module.cpp | 23 
> ++-
>  1 file changed, 22 insertions(+), 1 deletion(-)
> 
> diff --git a/src/gallium/state_trackers/clover/core/module.cpp 
> b/src/gallium/state_trackers/clover/core/module.cpp
> index 3e3ad99..41de734 100644
> --- a/src/gallium/state_trackers/clover/core/module.cpp
> +++ b/src/gallium/state_trackers/clover/core/module.cpp
> @@ -69,7 +69,9 @@ namespace {
>  
> /// (De)serialize a vector.
> template
> -   struct _serializer> {
> +   struct _serializer,
> +  typename std::enable_if<
> + !std::is_scalar::value>::type> {
>static void
>proc(compat::ostream &os, const compat::vector &v) {
>   _proc(os, v.size());
> @@ -87,6 +89,25 @@ namespace {
>}
> };
>  
> +   template
> +   struct _serializer,
> +  typename std::enable_if<
> + std::is_scalar::value>::type> {
> +  static void
> +  proc(compat::ostream &os, const compat::vector &v) {
> + _proc(os, v.size());
> + os.write(reinterpret_cast(v.begin()),
> +  v.size() * sizeof(T));
> +  }
> +
> +  static void
> +  proc(compat::istream &is, compat::vector &v) {
> + v.reserve(_proc(is));
> + is.read(reinterpret_cast(v.begin()),
> + v.size() * sizeof(T));
> +  }
> +   };
> +
> /// (De)serialize a module::section.
> template<>
> struct _serializer {
> -- 
> 1.9.2
> 

> From 1267038c2b0621dddc3d5c7718eed7ef2beb111b Mon Sep 17 00:00:00 2001
> From: Francisco Jerez 
> Date: Sat, 14 Jun 2014 21:03:02 +0200
> Subject: [PATCH 2/2] clover: Calculate the serialized size of a module
>  efficiently.
> 
> ---
>  src/gallium/state_trackers/clover/api/program.cpp |  5 +---
>  src/gallium/state_trackers/clover/core/module.cpp | 32 
> +++
>  src/gallium/state_trackers/clover/core/module.hpp |  1 +
>  3 files changed, 34 insertions(+), 4 deletions(-)
> 
> diff --git a/src/gallium/state_trackers/clover/api/program.cpp 
> b/src/gallium/state_trackers/clover/api/program.cpp
> index fedc91d..a14baa3 100644
> --- a/src/gallium/state_trackers/clover/api/program.cpp
> +++ b/src/gallium/state_trackers/clover/api/program.cpp
> @@ -190,10 +190,7 @@ clGetProgramInfo(cl_program d_prog, cl_program_info 
> param,
>  
> case CL_PROGRAM_BINARY_SIZES:
>buf.as_vector() = map([&](const device &dev) {
> -compat::ostream::buffer_t bin;
> -compat::ostream s(bin);
> -prog.binary(dev).serialize(s);
> -return bin.size();
> +return prog.binary(dev).size();
>   },
>   prog.devices());
>break;
> diff --git a/src/gallium/state_trackers/clover/core/module.cpp 
> b/src/gallium/state_trackers/clover/core/module.cpp
> index 41de734..55ed91a 100644
> --- a/src/gallium/state_trackers/clover/core/module.cpp
> +++ b/src/gallium/state_trackers/clover/core/module.cpp
> @@ -52,6 +52,13 @@ namespace {
>return x;
> }
>  
> +   /// Calculate the size of the specified object.
> +   template
> +   void
> +   _proc(module::size_t &sz, const T &x) {
> +  _serializer::proc(sz, x);
> +   }
> +
> /// (De)serialize a scalar value.
> template
> struct _serializer @@ -65,6 +72,11 @@ namespace {
>proc(compat::istream &is, T &x) {
>   is.read(reinterpret_cast(&x), sizeof(x));
>}
> +
> +  static void
> +  proc(module::size_t &sz, const T &x) {
> + sz += sizeof(x);
> +  }
> };
>  
> /// (De)serialize a vector.
> @@ -87,6 +99,14 @@ namespace {
>   for (size_t i = 0; i < v.size(); i++)
>  new(&v[i]) T(_proc(is));
>}
> +
> +  static void
> +  proc(module::size_t &sz, const compat::vector &v) {
> + sz += sizeof

Re: [Mesa-dev] [PATCH] clover: Cache serialized binaries

2014-06-15 Thread Francisco Jerez
Tom Stellard  writes:

> We were serializing the binaries once when clGetProgramInfo was called
> with CL_PROGRAM_BINARY_SIZES and then again when it was called with
> CL_PROGRAM_BINARIES.  This was slowing down some OpenCV tests which were
> building binary kernel caches.
>
> This improves the run-time of OpenCV's OCL_ImgProc/CvtColor8u.*
> test from 7 minutes to 1 minute.
> ---

Can you give the attached two patches a try?  I'm curious to see if they
have a comparable effect -- If they do I'd prefer to fix the underlying
object rather than caching binaries in serialized form.

Thanks.

>[...]

From a500126213b073793184b0b6f170a58229340778 Mon Sep 17 00:00:00 2001
From: Francisco Jerez 
Date: Sat, 14 Jun 2014 20:53:35 +0200
Subject: [PATCH 1/2] clover: Optimize module serialization for vectors of
 fundamental types.

---
 src/gallium/state_trackers/clover/core/module.cpp | 23 ++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/src/gallium/state_trackers/clover/core/module.cpp b/src/gallium/state_trackers/clover/core/module.cpp
index 3e3ad99..41de734 100644
--- a/src/gallium/state_trackers/clover/core/module.cpp
+++ b/src/gallium/state_trackers/clover/core/module.cpp
@@ -69,7 +69,9 @@ namespace {
 
/// (De)serialize a vector.
template
-   struct _serializer> {
+   struct _serializer,
+  typename std::enable_if<
+ !std::is_scalar::value>::type> {
   static void
   proc(compat::ostream &os, const compat::vector &v) {
  _proc(os, v.size());
@@ -87,6 +89,25 @@ namespace {
   }
};
 
+   template
+   struct _serializer,
+  typename std::enable_if<
+ std::is_scalar::value>::type> {
+  static void
+  proc(compat::ostream &os, const compat::vector &v) {
+ _proc(os, v.size());
+ os.write(reinterpret_cast(v.begin()),
+  v.size() * sizeof(T));
+  }
+
+  static void
+  proc(compat::istream &is, compat::vector &v) {
+ v.reserve(_proc(is));
+ is.read(reinterpret_cast(v.begin()),
+ v.size() * sizeof(T));
+  }
+   };
+
/// (De)serialize a module::section.
template<>
struct _serializer {
-- 
1.9.2

From 1267038c2b0621dddc3d5c7718eed7ef2beb111b Mon Sep 17 00:00:00 2001
From: Francisco Jerez 
Date: Sat, 14 Jun 2014 21:03:02 +0200
Subject: [PATCH 2/2] clover: Calculate the serialized size of a module
 efficiently.

---
 src/gallium/state_trackers/clover/api/program.cpp |  5 +---
 src/gallium/state_trackers/clover/core/module.cpp | 32 +++
 src/gallium/state_trackers/clover/core/module.hpp |  1 +
 3 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/src/gallium/state_trackers/clover/api/program.cpp b/src/gallium/state_trackers/clover/api/program.cpp
index fedc91d..a14baa3 100644
--- a/src/gallium/state_trackers/clover/api/program.cpp
+++ b/src/gallium/state_trackers/clover/api/program.cpp
@@ -190,10 +190,7 @@ clGetProgramInfo(cl_program d_prog, cl_program_info param,
 
case CL_PROGRAM_BINARY_SIZES:
   buf.as_vector() = map([&](const device &dev) {
-compat::ostream::buffer_t bin;
-compat::ostream s(bin);
-prog.binary(dev).serialize(s);
-return bin.size();
+return prog.binary(dev).size();
  },
  prog.devices());
   break;
diff --git a/src/gallium/state_trackers/clover/core/module.cpp b/src/gallium/state_trackers/clover/core/module.cpp
index 41de734..55ed91a 100644
--- a/src/gallium/state_trackers/clover/core/module.cpp
+++ b/src/gallium/state_trackers/clover/core/module.cpp
@@ -52,6 +52,13 @@ namespace {
   return x;
}
 
+   /// Calculate the size of the specified object.
+   template
+   void
+   _proc(module::size_t &sz, const T &x) {
+  _serializer::proc(sz, x);
+   }
+
/// (De)serialize a scalar value.
template
struct _serializer(&x), sizeof(x));
   }
+
+  static void
+  proc(module::size_t &sz, const T &x) {
+ sz += sizeof(x);
+  }
};
 
/// (De)serialize a vector.
@@ -87,6 +99,14 @@ namespace {
  for (size_t i = 0; i < v.size(); i++)
 new(&v[i]) T(_proc(is));
   }
+
+  static void
+  proc(module::size_t &sz, const compat::vector &v) {
+ sz += sizeof(uint32_t);
+
+ for (size_t i = 0; i < v.size(); i++)
+_proc(sz, v[i]);
+  }
};
 
template
@@ -106,6 +126,11 @@ namespace {
  is.read(reinterpret_cast(v.begin()),
  v.size() * sizeof(T));
   }
+
+  static void
+  proc(module::size_t &sz, const compat::vector &v) {
+ sz += sizeof(uint32_t) + sizeof(T) * v.size();
+  }
};
 
/// (De)serialize a module::section.
@@ -170,4 +195,11 @@ namespace clover {
module::deserialize(compat::istream &is) {
   return _proc(is);
}
+
+   module::size_t
+   module::size() const {
+  size_t