You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mxnet.apache.org by cj...@apache.org on 2017/10/28 15:44:57 UTC
[incubator-mxnet] branch master updated: Memset/memcpy/omp
profiling tester (#8380)
This is an automated email from the ASF dual-hosted git repository.
cjolivier01 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-mxnet.git
The following commit(s) were added to refs/heads/master by this push:
new eb08012 Memset/memcpy/omp profiling tester (#8380)
eb08012 is described below
commit eb08012097c598344709ad502d51eb70e2e21b59
Author: Chris Olivier <cj...@gmail.com>
AuthorDate: Sat Oct 28 08:44:53 2017 -0700
Memset/memcpy/omp profiling tester (#8380)
* Memory set/copy speed assertions
* Memory set/copy speed assertions
* ..
* ..
* ..
* ..
* bounce some cache
* lint
* Timing output for test_factorization_module when Verbose enabled (#8363)
* Timing output for test_factorization_module when Verbose enabled
* Trigger build
* Trigger build
* Trigger build
* Misc fixes for sparse distributed training (#8345)
* remove mshadow::range in init_op.h
* add unit test
* remove pass by ptr, add unit test for pull empty wieghts
* fix range in key partition
* remove wrong comment
* remove change for partition
* remove unused var
* add int64 to arange. add checkpointing example
* Fix the Readme (#8369)
* Allow test to converge (#8351)
* Allow test to converge
* Trigger build
* Trigger build
* Trigger build
* Update cudnn_algoreg-inl.h (#7988)
* [Perl] emulate Python zip() for Perl (#8192)
* [Perl] emulate Python zip() for Perl
* [Perl] retool zip() uses away from the callback form
* add profile option for frontend profiling to image script (#8171)
* add profile option for frontend profiling to image script
* Update image_classification.py
* Update image_classification.py
* Fix Typo (classification) (#8376)
Fix a typo in the example readme.
* Use omp_get_max_threads() when OMP_NUM_THREADS environment variable is set (#8379)
* CPU optimization for ActivationOp (#8296)
* CPU optimization for ActivationOp
Significant improvement on CPU (several magnitudes of order in some cases, especially on backward pass).
Very slight improvement on GPU.
OLD MSHADOW APPROACH
--------------------
CPU
===
Timing: 50 iterations of 10 calls, shape = [1,1,28,28]
Activation Operator CPU: Timing [Forward] 18.948 ms, avg: 0.037896 ms X 500 passes
Activation Operator CPU: Timing [Backward] 1.658 ms, avg: 0.003316 ms X 500 passes
Timing: 50 iterations of 10 calls, shape = [1,3,28,28]
Activation Operator CPU: Timing [Forward] 57.973 ms, avg: 0.115946 ms X 500 passes
Activation Operator CPU: Timing [Backward] 4.748 ms, avg: 0.009496 ms X 500 passes
Timing: 50 iterations of 10 calls, shape = [50,1,18,32]
Activation Operator CPU: Timing [Forward] 703.446 ms, avg: 1.40689 ms X 500 passes
Activation Operator CPU: Timing [Backward] 56.255 ms, avg: 0.11251 ms X 500 passes
Timing: 50 iterations of 10 calls, shape = [50,3,18,32]
Activation Operator CPU: Timing [Forward] 2107.77 ms, avg: 4.21554 ms X 500 passes
Activation Operator CPU: Timing [Backward] 168.483 ms, avg: 0.336966 ms X 500 passes
Timing: 50 iterations of 10 calls, shape = [20,3,128,128]
Activation Operator CPU: Timing [Forward] 24122.2 ms, avg: 48.2443 ms X 500 passes
Activation Operator CPU: Timing [Backward] 1908.7 ms, avg: 3.8174 ms X 500 passes
GPU
===
Timing: 50 iterations of 10 calls, shape = [1,1,28,28]
Activation Operator GPU: Timing [Forward] 1.637 ms, avg: 0.003274 ms X 500 passes
Activation Operator GPU: Timing [Backward] 1.665 ms, avg: 0.00333 ms X 500 passes
Timing: 50 iterations of 10 calls, shape = [1,3,28,28]
Activation Operator GPU: Timing [Forward] 1.562 ms, avg: 0.003124 ms X 500 passes
Activation Operator GPU: Timing [Backward] 1.661 ms, avg: 0.003322 ms X 500 passes
Timing: 50 iterations of 10 calls, shape = [50,1,18,32]
Activation Operator GPU: Timing [Forward] 1.635 ms, avg: 0.00327 ms X 500 passes
Activation Operator GPU: Timing [Backward] 1.702 ms, avg: 0.003404 ms X 500 passes
Timing: 50 iterations of 10 calls, shape = [50,3,18,32]
Activation Operator GPU: Timing [Forward] 1.83 ms, avg: 0.00366 ms X 500 passes
Activation Operator GPU: Timing [Backward] 2.041 ms, avg: 0.004082 ms X 500 passes
Timing: 50 iterations of 10 calls, shape = [20,3,128,128]
Activation Operator GPU: Timing [Forward] 2.08 ms, avg: 0.00416 ms X 500 passes
Activation Operator GPU: Timing [Backward] 2.688 ms, avg: 0.005376 ms X 500 passes
NEW MXNET_OP APPROACH
---------------------
CPU
===
Timing: 50 iterations of 10 calls, shape = [1,1,28,28]
Activation Operator CPU: Timing [Forward] 80.748 ms, avg: 0.161496 ms X 500 passes
Activation Operator CPU: Timing [Backward] 1.176 ms, avg: 0.002352 ms X 500 passes
Timing: 50 iterations of 10 calls, shape = [1,3,28,28]
Activation Operator CPU: Timing [Forward] 7.881 ms, avg: 0.015762 ms X 500 passes
Activation Operator CPU: Timing [Backward] 2.181 ms, avg: 0.004362 ms X 500 passes
Timing: 50 iterations of 10 calls, shape = [50,1,18,32]
Activation Operator CPU: Timing [Forward] 111.48 ms, avg: 0.22296 ms X 500 passes
Activation Operator CPU: Timing [Backward] 5.408 ms, avg: 0.010816 ms X 500 passes
Timing: 50 iterations of 10 calls, shape = [50,3,18,32]
Activation Operator CPU: Timing [Forward] 333.439 ms, avg: 0.666878 ms X 500 passes
Activation Operator CPU: Timing [Backward] 21.331 ms, avg: 0.042662 ms X 500 passes
Timing: 50 iterations of 10 calls, shape = [20,3,128,128]
Activation Operator CPU: Timing [Forward] 3429.19 ms, avg: 6.85837 ms X 500 passes
Activation Operator CPU: Timing [Backward] 286.324 ms, avg: 0.572648 ms X 500 passes
GPU
===
Timing: 50 iterations of 10 calls, shape = [1,1,28,28]
Activation Operator GPU: Timing [Forward] 1.618 ms, avg: 0.003236 ms X 500 passes
Activation Operator GPU: Timing [Backward] 1.671 ms, avg: 0.003342 ms X 500 passes
Timing: 50 iterations of 10 calls, shape = [1,3,28,28]
Activation Operator GPU: Timing [Forward] 1.629 ms, avg: 0.003258 ms X 500 passes
Activation Operator GPU: Timing [Backward] 1.728 ms, avg: 0.003456 ms X 500 passes
Timing: 50 iterations of 10 calls, shape = [50,1,18,32]
Activation Operator GPU: Timing [Forward] 1.753 ms, avg: 0.003506 ms X 500 passes
Activation Operator GPU: Timing [Backward] 1.756 ms, avg: 0.003512 ms X 500 passes
Timing: 50 iterations of 10 calls, shape = [50,3,18,32]
Activation Operator GPU: Timing [Forward] 1.704 ms, avg: 0.003408 ms X 500 passes
Activation Operator GPU: Timing [Backward] 1.791 ms, avg: 0.003582 ms X 500 passes
Timing: 50 iterations of 10 calls, shape = [20,3,128,128]
Activation Operator GPU: Timing [Forward] 2.032 ms, avg: 0.004064 ms X 500 passes
Activation Operator GPU: Timing [Backward] 2.143 ms, avg: 0.004286 ms X 500 passes
* lint
* Trigger build
* Trigger build
* Negative begin and end support for csr slice (#8241)
* negative index support for sparse slice
* fix lint
* getitem(int) for csr ndarray, support a[-1]
* remove unneccessary argument
* unittest and doc update
* Preparing for 0.12.0.rc0: Final changes before RC (#8301)
* Final changes before RC
* Updates to NEWS.md
* Updates
* Enable smoothing in softmax operator (#8125)
* v0.12 regression: Fix registration of children for Block (#8277)
* Fix Block not registering children
If the attribute was already set to something different than Block (e.g. None),
it was not being registered.
* fix if / elif for block children registration
* trigger test
* Add fix from #8152
* Add tests from #8152
* Revert "[CMAKE] Fix windows cmake build" (#8311)
* Revert "Added my code signing key (#8293)"
This reverts commit 22ab185bbfde0ac2d801ec700ac4705ef0ee8daa.
* Revert "[CMAKE] Fix windows cmake build (#8227)"
This reverts commit 1c1c788916d672ee3cafdc4c91d7002a94a59d13.
* fixed broken links. https was pointing to http for mxnet.io (#8300)
* Update rnn.md (#8320)
* fluent methods for missed ops (#8329)
* update ps lite (#8327)
* Fix unused type warning (#8316)
* Trigger build
* Trigger build
* Misc fixes for sparse distributed training (#8345)
* remove mshadow::range in init_op.h
* add unit test
* remove pass by ptr, add unit test for pull empty wieghts
* fix range in key partition
* remove wrong comment
* remove change for partition
* remove unused var
* add int64 to arange. add checkpointing example
* Fix the Readme (#8369)
* Allow test to converge (#8351)
* Allow test to converge
* Trigger build
* Trigger build
* Trigger build
* Update cudnn_algoreg-inl.h (#7988)
* [Perl] emulate Python zip() for Perl (#8192)
* [Perl] emulate Python zip() for Perl
* [Perl] retool zip() uses away from the callback form
* add profile option for frontend profiling to image script (#8171)
* add profile option for frontend profiling to image script
* Update image_classification.py
* Update image_classification.py
* Fix Typo (classification) (#8376)
Fix a typo in the example readme.
* do gtest test
* add assert and do higher runs as performance test only (when performance test flag set)
* Trigger build
* lint
* Trigger build
* Sparse operator performance improvement (#8412)
* sparse rsprsp perf improvements
* Clean up
* dtype default to source_array.dtype for sparse ndarrays (#8403)
* derive default dtype/ctx from input for sparse ndarrays
* add gpu tests
* fix lint. add doc
* remove default_ctx code
* bug fix when passing dtype to array()
* update doc
* remove extra line
* also check ctx
* fix using default mean pixels (#8352)
* fix gluon.data.RecordFileDataset (#8353)
* upgrade MKL (#8378)
* Lint fix (#8402)
* Trigger build
---
tests/cpp/include/test_perf.h | 19 ++++++
tests/cpp/misc/memory_test.cc | 145 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 164 insertions(+)
diff --git a/tests/cpp/include/test_perf.h b/tests/cpp/include/test_perf.h
index d74d4d5..b6f2145 100644
--- a/tests/cpp/include/test_perf.h
+++ b/tests/cpp/include/test_perf.h
@@ -60,6 +60,25 @@ inline uint64_t getMicroTickCount() {
#endif
}
+/*! \brief current timestamp: millionths of a second */
+inline uint64_t getNannoTickCount() {
+#ifndef _WIN32
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return (uint64_t(tv.tv_sec) * 1000000 + tv.tv_usec) * 1000;
+#else
+ LARGE_INTEGER CurrentTime;
+ LARGE_INTEGER Frequency;
+
+ QueryPerformanceFrequency(&Frequency);
+ QueryPerformanceCounter(&CurrentTime);
+
+ CurrentTime.QuadPart *= 1000000000;
+ CurrentTime.QuadPart /= Frequency.QuadPart;
+ return CurrentTime.QuadPart;
+#endif
+}
+
/*! \brief millisecond tick count */
inline uint64_t getTickCount() {
return getMicroTickCount() / 1000;
diff --git a/tests/cpp/misc/memory_test.cc b/tests/cpp/misc/memory_test.cc
new file mode 100644
index 0000000..e39399d
--- /dev/null
+++ b/tests/cpp/misc/memory_test.cc
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*!
+ * \file memory_test.cc
+ * \brief Perf/profile run of ActivationOp
+ * \author Chris Olivier
+ */
+
+#include <gtest/gtest.h>
+#include <dmlc/omp.h>
+#include <mxnet/tensor_blob.h>
+#include "../include/test_util.h"
+#include "../include/test_perf.h"
+
+using namespace mxnet;
+
+#ifdef _OPENMP
+template<typename Container>
+static typename Container::value_type average(const Container& cont) {
+ typename Container::value_type avg = 0;
+ const size_t sz = cont.size();
+ for (auto iter = cont.begin(), e_iter = cont.end(); iter != e_iter; ++iter) {
+ avg += *iter / sz; // Attempt to not overflow by dividing up incrementally
+ }
+ return avg;
+}
+
+static std::string pretty_num(uint64_t val) {
+ std::string res, s = std::to_string(val);
+ size_t ctr = 0;
+ for (int i = static_cast<int>(s.size()) - 1; i >= 0; --i, ++ctr) {
+ if (ctr && (ctr % 3) == 0) {
+ res += ",";
+ }
+ res.push_back(s[i]);
+ }
+ std::reverse(res.begin(), res.end());
+ return res;
+}
+
+static int GetOMPThreadCount() {
+ return omp_get_max_threads() >> 1;
+}
+
+/*!
+ * \brief Generic bidirectional sanity test
+ */
+TEST(MEMORY_TEST, MemsetAndMemcopyPerformance) {
+ const size_t GB = 1000000000; // memset never slower
+ uint64_t base = 100000;
+ std::list<uint64_t> memset_times, omp_set_times, memcpy_times, omp_copy_times;
+ size_t pass = 0;
+ do {
+ memset_times.resize(0);
+ omp_set_times.resize(0);
+ memcpy_times.resize(0);
+ omp_copy_times.resize(0);;
+
+ const size_t test_size = 2 * base;
+ std::cout << "====================================" << std::endl
+ << "Data size: " << pretty_num(test_size) << std::endl << std::flush;
+
+ std::unique_ptr<uint8_t> buffer_1(new uint8_t[test_size]), buffer_2(new uint8_t[test_size]);
+ uint8_t *src = buffer_1.get(), *dest = buffer_2.get();
+
+ for (size_t x = 0; x < 5; ++x) {
+ // Init memory with different values
+ memset(src, 3, test_size);
+ memset(dest, 255, test_size); // wipe out some/all of src cache
+
+ // memset
+ uint64_t start = test::perf::getNannoTickCount();
+ memset(src, 123, test_size);
+ const uint64_t memset_time = test::perf::getNannoTickCount() - start;
+
+ start = test::perf::getNannoTickCount();
+ #pragma omp parallel for num_threads(GetOMPThreadCount())
+ for (int i = 0; i < test_size; ++i) {
+ src[i] = 42;
+ }
+ const uint64_t omp_set_time = test::perf::getNannoTickCount() - start;
+
+ start = test::perf::getNannoTickCount();
+ memcpy(dest, src, test_size);
+ const uint64_t memcpy_time = test::perf::getNannoTickCount() - start;
+
+ // bounce the cache and dirty logic
+ memset(src, 6, test_size);
+ memset(dest, 200, test_size);
+
+ start = test::perf::getNannoTickCount();
+ #pragma omp parallel for num_threads(GetOMPThreadCount())
+ for (int i = 0; i < test_size; ++i) {
+ dest[i] = src[i];
+ }
+ const uint64_t omp_copy_time = test::perf::getNannoTickCount() - start;
+
+ memset_times.push_back(memset_time);
+ omp_set_times.push_back(omp_set_time);
+ memcpy_times.push_back(memcpy_time);
+ omp_copy_times.push_back(omp_copy_time);
+
+ std::cout << "memset time: " << pretty_num(memcpy_time) << " ns" << std::endl
+ << "omp set time: " << pretty_num(omp_set_time) << " ns" << std::endl
+ << std::endl;
+ std::cout << "memcpy time: " << pretty_num(memcpy_time) << " ns" << std::endl
+ << "omp copy time: " << pretty_num(omp_copy_time) << " ns" << std::endl
+ << std::endl;
+ }
+ std::cout << "------------------------------------" << std::endl;
+ if (average(memset_times) > average(omp_set_times)) {
+ std::cout << "<< MEMSET SLOWER FOR " << pretty_num(test_size) << " items >>" << std::endl;
+ }
+ if (average(memcpy_times) > average(omp_copy_times)) {
+ std::cout << "<< MEMCPY SLOWER FOR " << pretty_num(test_size) << " items >>" << std::endl;
+ }
+ if (!pass) {
+ GTEST_ASSERT_LE(average(memset_times), average(omp_set_times));
+ GTEST_ASSERT_LE(average(memcpy_times), average(omp_copy_times));
+ }
+ base *= 10;
+ ++pass;
+ } while (test::performance_run
+ && base <= GB
+ && (average(memset_times) < average(omp_set_times)
+ || average(memcpy_times), average(omp_copy_times)));
+}
+#endif // _OPENMP
--
To stop receiving notification emails like this one, please contact
['"commits@mxnet.apache.org" <co...@mxnet.apache.org>'].