You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by mz...@apache.org on 2019/08/23 21:51:44 UTC

[mesos] branch master updated (978c760 -> 7303313)

This is an automated email from the ASF dual-hosted git repository.

mzhu pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git.


    from 978c760  Sped up `ExampleTest.DiskFullFramework` test.
     new ec6b7b3  Optimized the allocation loop.
     new 25070f2  Updated the boost library.
     new 95201cb  Used boost `small_vector` in Resource Quantities and Limits.
     new 7303313  Used boost `small_vector` in `Resources`.

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 3rdparty/boost-1.65.0.tar.gz                | Bin 1814636 -> 1202770 bytes
 3rdparty/boost.md                           |   2 +-
 3rdparty/cmake/Versions.cmake               |   2 +-
 include/mesos/resource_quantities.hpp       |  33 +++++++----
 include/mesos/resources.hpp                 |  20 ++++---
 include/mesos/v1/resources.hpp              |  20 ++++---
 src/common/resource_quantities.cpp          |  34 ++++-------
 src/master/allocator/mesos/hierarchical.cpp |  86 +++++++++++++++++-----------
 8 files changed, 111 insertions(+), 86 deletions(-)


[mesos] 02/04: Updated the boost library.

Posted by mz...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mzhu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git

commit 25070f232a9bb97d1b78f8a7e5b774bbd50654f9
Author: Meng Zhu <mz...@mesosphere.io>
AuthorDate: Thu Aug 22 16:54:42 2019 -0700

    Updated the boost library.
    
    This update includes adding `container/small_vector.hpp`.
    
    Review: https://reviews.apache.org/r/71356
---
 3rdparty/boost-1.65.0.tar.gz  | Bin 1814636 -> 1202770 bytes
 3rdparty/boost.md             |   2 +-
 3rdparty/cmake/Versions.cmake |   2 +-
 3 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/3rdparty/boost-1.65.0.tar.gz b/3rdparty/boost-1.65.0.tar.gz
index e9f02d7..b09d185 100644
Binary files a/3rdparty/boost-1.65.0.tar.gz and b/3rdparty/boost-1.65.0.tar.gz differ
diff --git a/3rdparty/boost.md b/3rdparty/boost.md
index e6373f2..d6e482f 100644
--- a/3rdparty/boost.md
+++ b/3rdparty/boost.md
@@ -34,7 +34,7 @@ See: http://www.boost.org/doc/libs/1_65_0/tools/bcp/doc/html/index.html
 # Update 3rdparty/cmake/Versions.cmake with the new version and
 #  its SHA-256 hash. You can obtain the hash as follows, make sure
 #  to do this on the stripped release:
-  $ openssl sha -sha256 3rdparty/boost-1.65.0.tar.gz
+  $ openssl sha256 3rdparty/boost-1.65.0.tar.gz
 
 
 # Update this README if needed.
diff --git a/3rdparty/cmake/Versions.cmake b/3rdparty/cmake/Versions.cmake
index 0788e61..9376616 100644
--- a/3rdparty/cmake/Versions.cmake
+++ b/3rdparty/cmake/Versions.cmake
@@ -1,5 +1,5 @@
 set(BOOST_VERSION           "1.65.0")
-set(BOOST_HASH              "SHA256=0442df595dc56e7da11665120ce9d92ec40c192eb060488131b346bac0938ba3")
+set(BOOST_HASH              "SHA256=607a5ce234ba8bdf30764eec233fd91211c0228e4cb6bd3f389e6f269bd9aea2")
 set(CONCURRENTQUEUE_VERSION "7b69a8f")
 set(CONCURRENTQUEUE_HASH    "SHA256=B2741A1FB2172C2A829503A85D5EE7548BE7ED04236A3FD1EFD2B6088E065CB7")
 set(CSI_V0_VERSION          "0.2.0")


[mesos] 04/04: Used boost `small_vector` in `Resources`.

Posted by mz...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mzhu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git

commit 73033130de7872c6f240b9b05dced039d7666138
Author: Meng Zhu <mz...@mesosphere.io>
AuthorDate: Thu Aug 22 17:19:30 2019 -0700

    Used boost `small_vector` in `Resources`.
    
    Master + previous patch:
    *HierarchicalAllocator_WithQuotaParam.LargeAndSmallQuota/2
    Made 3500 allocations in 16.307044003secs
    Made 0 allocation in 14.948262599secs
    
    Master + previous patch + this patch:
    *HierarchicalAllocator_WithQuotaParam.LargeAndSmallQuota/2
    Made 3500 allocations in 15.385276405secs
    Made 0 allocation in 13.718502414secs
    
    Review: https://reviews.apache.org/r/71357
---
 include/mesos/resources.hpp    | 20 ++++++++++++--------
 include/mesos/v1/resources.hpp | 20 ++++++++++++--------
 2 files changed, 24 insertions(+), 16 deletions(-)

diff --git a/include/mesos/resources.hpp b/include/mesos/resources.hpp
index e5e87a0..b8aef28 100644
--- a/include/mesos/resources.hpp
+++ b/include/mesos/resources.hpp
@@ -23,6 +23,7 @@
 #include <string>
 #include <vector>
 
+#include <boost/container/small_vector.hpp>
 #include <boost/iterator/indirect_iterator.hpp>
 
 #include <google/protobuf/repeated_field.h>
@@ -630,21 +631,19 @@ public:
   // iterators to prevent mutable access to the `Resource` objects.
 
   typedef boost::indirect_iterator<
-      std::vector<Resource_Unsafe>::const_iterator>
+      boost::container::small_vector_base<Resource_Unsafe>::const_iterator>
     const_iterator;
 
   const_iterator begin()
   {
-    return static_cast<const std::vector<Resource_Unsafe>&>(
-               resourcesNoMutationWithoutExclusiveOwnership)
-      .begin();
+    const auto& self = *this;
+    return self.begin();
   }
 
   const_iterator end()
   {
-    return static_cast<const std::vector<Resource_Unsafe>&>(
-               resourcesNoMutationWithoutExclusiveOwnership)
-      .end();
+    const auto& self = *this;
+    return self.end();
   }
 
   const_iterator begin() const
@@ -754,7 +753,12 @@ private:
   //
   // TODO(mzhu): Consider using `boost::intrusive_ptr` for
   // possibly better performance.
-  std::vector<Resource_Unsafe> resourcesNoMutationWithoutExclusiveOwnership;
+  //
+  // We chose a size of 15 based on the fact that we have five first class
+  // resources (cpu, mem, disk, gpu and port). And 15 would allow one set of
+  // unreserved resources and two sets of reservations.
+  boost::container::small_vector<Resource_Unsafe, 15>
+    resourcesNoMutationWithoutExclusiveOwnership;
 };
 
 
diff --git a/include/mesos/v1/resources.hpp b/include/mesos/v1/resources.hpp
index 6a9751a..3fbe7fb 100644
--- a/include/mesos/v1/resources.hpp
+++ b/include/mesos/v1/resources.hpp
@@ -23,6 +23,7 @@
 #include <string>
 #include <vector>
 
+#include <boost/container/small_vector.hpp>
 #include <boost/iterator/indirect_iterator.hpp>
 
 #include <google/protobuf/repeated_field.h>
@@ -625,21 +626,19 @@ public:
   // iterators to prevent mutable access to the `Resource` objects.
 
   typedef boost::indirect_iterator<
-      std::vector<Resource_Unsafe>::const_iterator>
+      boost::container::small_vector_base<Resource_Unsafe>::const_iterator>
     const_iterator;
 
   const_iterator begin()
   {
-    return static_cast<const std::vector<Resource_Unsafe>&>(
-               resourcesNoMutationWithoutExclusiveOwnership)
-      .begin();
+    const auto& self = *this;
+    return self.begin();
   }
 
   const_iterator end()
   {
-    return static_cast<const std::vector<Resource_Unsafe>&>(
-               resourcesNoMutationWithoutExclusiveOwnership)
-      .end();
+    const auto& self = *this;
+    return self.end();
   }
 
   const_iterator begin() const
@@ -749,7 +748,12 @@ private:
   //
   // TODO(mzhu): Consider using `boost::intrusive_ptr` for
   // possibly better performance.
-  std::vector<Resource_Unsafe> resourcesNoMutationWithoutExclusiveOwnership;
+  //
+  // We chose a size of 15 based on the fact that we have five first class
+  // resources (cpu, mem, disk, gpu and port). And 15 would allow one set of
+  // unreserved resources and two sets of reservations.
+  boost::container::small_vector<Resource_Unsafe, 15>
+    resourcesNoMutationWithoutExclusiveOwnership;
 };
 
 


[mesos] 01/04: Optimized the allocation loop.

Posted by mz...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mzhu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git

commit ec6b7b34215e821a63cb79e7d52d94ff08c1e110
Author: Meng Zhu <mz...@mesosphere.io>
AuthorDate: Thu Aug 22 17:54:25 2019 -0700

    Optimized the allocation loop.
    
    Master:
    
    HierarchicalAllocator_WithQuotaParam.LargeAndSmallQuota/2
    Made 3500 allocations in 23.37 secs
    Made 0 allocation in 19.72 secs
    
    Master + this patch:
    
    HierarchicalAllocator_WithQuotaParam.LargeAndSmallQuota/2
    Made 3500 allocations in 16.831380548secs
    Made 0 allocation in 15.102885644secs
    
    Review: https://reviews.apache.org/r/71359
---
 src/master/allocator/mesos/hierarchical.cpp | 86 ++++++++++++++++++-----------
 1 file changed, 53 insertions(+), 33 deletions(-)

diff --git a/src/master/allocator/mesos/hierarchical.cpp b/src/master/allocator/mesos/hierarchical.cpp
index 649de3b..dd73d5b 100644
--- a/src/master/allocator/mesos/hierarchical.cpp
+++ b/src/master/allocator/mesos/hierarchical.cpp
@@ -1965,16 +1965,30 @@ void HierarchicalAllocatorProcess::__allocate()
         break; // Nothing left on this agent.
       }
 
+      ResourceQuantities unsatisfiedQuotaGuarantees =
+        quotaGuarantees -
+        rolesConsumedQuota.get(role).getOrElse(ResourceQuantities());
+
+      // We only allocate to roles with unsatisfied guarantees
+      // in the first stage.
+      if (unsatisfiedQuotaGuarantees.empty()) {
+        continue;
+      }
+
       // Fetch frameworks in the order provided by the sorter.
       // NOTE: Suppressed frameworks are not included in the sort.
       Sorter* frameworkSorter = CHECK_NOTNONE(getFrameworkSorter(role));
 
       foreach (const string& frameworkId_, frameworkSorter->sort()) {
-        Resources available = slave.getAvailable().allocatableTo(role);
+        if (unsatisfiedQuotaGuarantees.empty()) {
+          break;
+        }
 
         // Offer a shared resource only if it has not been offered in this
         // offer cycle to a framework.
-        available -= offeredSharedResources.get(slaveId).getOrElse(Resources());
+        Resources available =
+          slave.getAvailable().allocatableTo(role) -
+          offeredSharedResources.get(slaveId).getOrElse(Resources());
 
         if (available.empty()) {
           break; // Nothing left for the role.
@@ -2048,13 +2062,16 @@ void HierarchicalAllocatorProcess::__allocate()
         // which only enforces quantity. Nevertheless, We choose to allow
         // such bursting for less resource fragmentation.
 
-        ResourceQuantities unsatisfiedQuotaGuarantees =
-          quotaGuarantees -
-          rolesConsumedQuota.get(role).getOrElse(ResourceQuantities());
-
         // Resources that can be used to to increase a role's quota consumption.
+        //
+        // This is hot path, we use explicit filter calls to avoid
+        // multiple traversal.
         Resources quotaResources =
-          available.scalars().unreserved().nonRevocable();
+          available.filter([&](const Resource& resource) {
+            return resource.type() == Value::SCALAR &&
+                   Resources::isUnreserved(resource) &&
+                   !Resources::isRevocable(resource);
+          });
 
         Resources guaranteesAllocation =
           shrinkResources(quotaResources, unsatisfiedQuotaGuarantees);
@@ -2076,17 +2093,23 @@ void HierarchicalAllocatorProcess::__allocate()
           continue;
         }
 
-        // First, reservations and guarantees are always allocated.
+        // This role's reservations, non-scalar resources and revocable
+        // resources, as well as guarantees are always allocated.
         //
         // We need to allocate guarantees unconditionally here so that
         // even the cluster is overcommitted by guarantees (thus deficit in
         // headroom), this role's guarantees can still be allocated.
-        Resources toAllocate = available.reserved(role) + guaranteesAllocation;
+        Resources toAllocate = guaranteesAllocation +
+                               available.filter([&](const Resource& resource) {
+                                 return Resources::isReserved(resource, role) ||
+                                        resource.type() != Value::SCALAR ||
+                                        Resources::isRevocable(resource);
+                               });
 
         Resources additionalScalarAllocation =
           quotaResources - guaranteesAllocation;
 
-        // Second, non-guaranteed quota resources are subject to quota limits
+        // Then, non-guaranteed quota resources are subject to quota limits
         // and global headroom enforcements.
 
         // Limits enforcement.
@@ -2112,13 +2135,6 @@ void HierarchicalAllocatorProcess::__allocate()
 
         toAllocate += additionalScalarAllocation;
 
-        // Lastly, non-scalar resources and revocable resources
-        // are all allocated.
-        toAllocate += available.filter([&](const Resource& resource) {
-          return resource.type() != Value::SCALAR ||
-                 Resources::isRevocable(resource);
-        });
-
         // If the framework filters these resources, ignore.
         if (!allocatable(toAllocate, role, framework) ||
             isFiltered(framework, role, slave, toAllocate)) {
@@ -2140,6 +2156,7 @@ void HierarchicalAllocatorProcess::__allocate()
           ResourceQuantities::fromScalarResources(
               guaranteesAllocation + additionalScalarAllocation);
 
+        unsatisfiedQuotaGuarantees -= increasedQuotaConsumption;
         rolesConsumedQuota[role] += increasedQuotaConsumption;
         for (const string& ancestor : roles::ancestors(role)) {
           rolesConsumedQuota[ancestor] += increasedQuotaConsumption;
@@ -2196,11 +2213,11 @@ void HierarchicalAllocatorProcess::__allocate()
       Sorter* frameworkSorter = CHECK_NOTNONE(getFrameworkSorter(role));
 
       foreach (const string& frameworkId_, frameworkSorter->sort()) {
-        Resources available = slave.getAvailable().allocatableTo(role);
-
         // Offer a shared resource only if it has not been offered in this
         // offer cycle to a framework.
-        available -= offeredSharedResources.get(slaveId).getOrElse(Resources());
+        Resources available =
+          slave.getAvailable().allocatableTo(role) -
+          offeredSharedResources.get(slaveId).getOrElse(Resources());
 
         if (available.empty()) {
           break; // Nothing left for the role.
@@ -2222,15 +2239,25 @@ void HierarchicalAllocatorProcess::__allocate()
 
         available = stripIncapableResources(available, framework.capabilities);
 
-        // First, reservations are always allocated. This also includes the
-        // roles ancestors' reservations.
-        Resources toAllocate = available.reserved();
+        // Reservations (including the roles ancestors' reservations),
+        // non-scalar resources and revocable resources are always allocated.
+        Resources toAllocate = available.filter([&](const Resource& resource) {
+          return Resources::isReserved(resource) ||
+                 resource.type() != Value::SCALAR ||
+                 Resources::isRevocable(resource);
+        });
 
-        // Second, unreserved scalar resources are subject to quota limits
+        // Then, unreserved scalar resources are subject to quota limits
         // and global headroom enforcement.
-
+        //
+        // This is hot path, we use explicit filter calls to avoid
+        // multiple traversal.
         Resources additionalScalarAllocation =
-          available.scalars().unreserved().nonRevocable();
+          available.filter([&](const Resource& resource) {
+            return resource.type() == Value::SCALAR &&
+                   Resources::isUnreserved(resource) &&
+                   !Resources::isRevocable(resource);
+          });
 
         // Limits enforcement.
         if (!quotaLimits.empty()) {
@@ -2258,13 +2285,6 @@ void HierarchicalAllocatorProcess::__allocate()
 
         toAllocate += additionalScalarAllocation;
 
-        // Lastly, non-scalar resources and revocable resources
-        // are all allocated.
-        toAllocate += available.filter([&](const Resource& resource) {
-          return resource.type() != Value::SCALAR ||
-                 Resources::isRevocable(resource);
-        });
-
         // If the framework filters these resources, ignore.
         if (!allocatable(toAllocate, role, framework) ||
             isFiltered(framework, role, slave, toAllocate)) {


[mesos] 03/04: Used boost `small_vector` in Resource Quantities and Limits.

Posted by mz...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mzhu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git

commit 95201cbe4dc87eae2fde5754d16f5effbb6c1974
Author: Meng Zhu <mz...@mesosphere.io>
AuthorDate: Thu Aug 22 16:55:34 2019 -0700

    Used boost `small_vector` in Resource Quantities and Limits.
    
    Master + previous patch
    *HierarchicalAllocator_WithQuotaParam.LargeAndSmallQuota/2
    Made 3500 allocations in 16.831380548secs
    Made 0 allocation in 15.102885644secs
    
    Master + previous patch + this patch:
    *HierarchicalAllocator_WithQuotaParam.LargeAndSmallQuota/2
    Made 3500 allocations in 16.307044003secs
    Made 0 allocation in 14.948262599secs
    
    Review: https://reviews.apache.org/r/71355
---
 include/mesos/resource_quantities.hpp | 33 ++++++++++++++++++++++-----------
 src/common/resource_quantities.cpp    | 34 ++++++++++------------------------
 2 files changed, 32 insertions(+), 35 deletions(-)

diff --git a/include/mesos/resource_quantities.hpp b/include/mesos/resource_quantities.hpp
index cdb3427..8195d5e 100644
--- a/include/mesos/resource_quantities.hpp
+++ b/include/mesos/resource_quantities.hpp
@@ -19,7 +19,8 @@
 
 #include <string>
 #include <utility>
-#include <vector>
+
+#include <boost/container/small_vector.hpp>
 
 #include <mesos/mesos.hpp>
 
@@ -118,10 +119,10 @@ public:
   ResourceQuantities& operator=(const ResourceQuantities& that) = default;
   ResourceQuantities& operator=(ResourceQuantities&& that) = default;
 
-  typedef std::vector<std::pair<std::string, Value::Scalar>>::const_iterator
-    iterator;
-  typedef std::vector<std::pair<std::string, Value::Scalar>>::const_iterator
-    const_iterator;
+  typedef boost::container::small_vector_base<
+      std::pair<std::string, Value::Scalar> >::const_iterator iterator;
+  typedef boost::container::small_vector_base<
+      std::pair<std::string, Value::Scalar> >::const_iterator const_iterator;
 
   // NOTE: Non-`const` `iterator`, `begin()` and `end()` are __intentionally__
   // defined with `const` semantics in order to prevent mutation during
@@ -159,7 +160,12 @@ private:
 
   // List of name quantity pairs sorted by name.
   // Arithmetic and comparison operations benefit from this sorting.
-  std::vector<std::pair<std::string, Value::Scalar>> quantities;
+  //
+  // Pre-allocate space for first-class resources, plus some margins.
+  // This needs to be updated as introduce more first-class resources.
+  // [cpus, disk, gpus, mem, ports]
+  boost::container::small_vector<std::pair<std::string, Value::Scalar>, 7>
+    quantities;
 };
 
 
@@ -212,10 +218,10 @@ public:
   ResourceLimits& operator=(const ResourceLimits& that) = default;
   ResourceLimits& operator=(ResourceLimits&& that) = default;
 
-  typedef std::vector<std::pair<std::string, Value::Scalar>>::const_iterator
-    iterator;
-  typedef std::vector<std::pair<std::string, Value::Scalar>>::const_iterator
-    const_iterator;
+  typedef boost::container::small_vector_base<
+      std::pair<std::string, Value::Scalar> >::const_iterator iterator;
+  typedef boost::container::small_vector_base<
+      std::pair<std::string, Value::Scalar> >::const_iterator const_iterator;
 
   // NOTE: Non-`const` `iterator`, `begin()` and `end()` are __intentionally__
   // defined with `const` semantics in order to prevent mutation during
@@ -258,7 +264,12 @@ private:
 
   // List of name limit pairs sorted by name.
   // Arithmetic and comparison operations benefit from this sorting.
-  std::vector<std::pair<std::string, Value::Scalar>> limits;
+  //
+  // Pre-allocate space for first-class resources, plus some margins.
+  // This needs to be updated as introduce more first-class resources.
+  // [cpus, disk, gpus, mem, ports]
+  boost::container::small_vector<std::pair<std::string, Value::Scalar>, 7>
+    limits;
 };
 
 
diff --git a/src/common/resource_quantities.cpp b/src/common/resource_quantities.cpp
index 7c7ede3..8f487fb 100644
--- a/src/common/resource_quantities.cpp
+++ b/src/common/resource_quantities.cpp
@@ -131,12 +131,7 @@ ResourceQuantities ResourceQuantities::fromResources(const Resources& resources)
 }
 
 
-ResourceQuantities::ResourceQuantities()
-{
-  // Pre-reserve space for first-class resources.
-  // [cpus, disk, gpus, mem, ports]
-  quantities.reserve(5u);
-}
+ResourceQuantities::ResourceQuantities() {}
 
 
 ResourceQuantities::ResourceQuantities(
@@ -152,17 +147,15 @@ ResourceQuantities::ResourceQuantities(
 
 ResourceQuantities::const_iterator ResourceQuantities::begin()
 {
-  return static_cast<const std::vector<std::pair<std::string, Value::Scalar>>&>(
-             quantities)
-    .begin();
+  const auto& self = *this;
+  return self.begin();
 }
 
 
 ResourceQuantities::const_iterator ResourceQuantities::end()
 {
-  return static_cast<const std::vector<std::pair<std::string, Value::Scalar>>&>(
-             quantities)
-    .end();
+  const auto& self = *this;
+  return self.end();
 }
 
 
@@ -407,12 +400,7 @@ Try<ResourceLimits> ResourceLimits::fromString(const string& text)
 }
 
 
-ResourceLimits::ResourceLimits()
-{
-  // Pre-reserve space for first-class resources.
-  // [cpus, disk, gpus, mem, ports]
-  limits.reserve(5u);
-}
+ResourceLimits::ResourceLimits() {}
 
 
 ResourceLimits::ResourceLimits(
@@ -428,17 +416,15 @@ ResourceLimits::ResourceLimits(
 
 ResourceLimits::const_iterator ResourceLimits::begin()
 {
-  return static_cast<const std::vector<std::pair<std::string, Value::Scalar>>&>(
-           limits)
-    .begin();
+  const auto& self = *this;
+  return self.begin();
 }
 
 
 ResourceLimits::const_iterator ResourceLimits::end()
 {
-  return static_cast<const std::vector<std::pair<std::string, Value::Scalar>>&>(
-           limits)
-    .end();
+  const auto& self = *this;
+  return self.end();
 }