Re: [Mesa-dev] [PATCH] clover: Cache serialized binaries
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
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