Skip to content

Commit

Permalink
optionally use huge pages in the allocator...only for linux for now
Browse files Browse the repository at this point in the history
  • Loading branch information
gblelloch committed Sep 20, 2024
1 parent 583624a commit 1f05a2f
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 16 deletions.
19 changes: 8 additions & 11 deletions examples/convex_hull_3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,21 @@ struct triangle {
// opposite side of a plane defined by three other points (a, b, c).
// It first takes the 4 points (a, b, c, p) and returns a function
// which takes the point q, answering the query. Since we often check
// multiple points against a single circle this reduces the work.
// multiple points q for being opposite to p, this reduces the work.
// Works by taking the cross product of c->a and c->b and checking that
// the dot of this with c->p and c->q have opposite signs.
inline auto is_opposite (point a, point b, point c, point p) {
auto v_from_c = [=] (point p) { return vect(p.x - c.x, p.y - c.y, p.z - c.z);};
auto minus = [] (point p1, point p2) { return vect(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z);};
auto dot = [] (vect v1, vect v2) { return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;};
auto cross = [] (vect v1, vect v2) {
return vect{v1.y*v2.z - v1.z*v2.y,
v1.z*v2.x - v1.x*v2.z,
v1.x*v2.y - v1.y*v2.x};};
vect cp = cross(v_from_c(a), v_from_c(b));
bool p_side = dot(cp, v_from_c(p)) > 0.0;
vect cp = cross(minus(a, c), minus(b, c));
bool p_side = dot(cp, minus(p, c)) > 0.0;
return [=] (point q) -> bool {
return ((dot(cp, v_from_c(q)) > 0.0) != p_side);};
bool q_side = dot(cp, minus(q, c)) > 0.0;
return (q_side != p_side);};
}

// **************************************************************
Expand All @@ -72,8 +73,8 @@ using Points = parlay::sequence<point>;
struct Convex_Hull_3d {
using triangle_ptr = std::shared_ptr<triangle>;
hash_map<edge, triangle_ptr> map_facets;
Points points;
hash_map<tri, bool> convex_hull;
Points points;
point_id n;

point_id min_conflicts(triangle_ptr& t) {
Expand All @@ -83,13 +84,11 @@ struct Convex_Hull_3d {
// convex hull in 3d space
void process_ridge(triangle_ptr& t1, edge r, triangle_ptr& t2) {
if (t1->conflicts.size() == 0 && t2->conflicts.size() == 0) {
t1 = t2 = nullptr; // allow to be reclaimed
return;
} else if (min_conflicts(t2) == min_conflicts(t1)) {
// H \ {t1, t2}
convex_hull.remove(t1->t);
convex_hull.remove(t2->t);
t1 = t2 = nullptr; // allow to be reclaimed
} else if (min_conflicts(t2) < min_conflicts(t1)) {
process_ridge(t2, r, t1);
} else {
Expand All @@ -111,7 +110,6 @@ struct Convex_Hull_3d {
// H <- (H \ {t1}) U {t}
convex_hull.remove(t1->t);
convex_hull.insert(t, true);
t1 = nullptr; // allow to be reclaimed

auto check_edge = [&] (edge e, triangle_ptr& tp) {
auto key = (e[0] < e[1]) ? e : edge{e[1], e[0]};
Expand All @@ -128,7 +126,7 @@ struct Convex_Hull_3d {

// toplevel routine
// The result is set of facets: result_facets
// assum that P has more than 4 points
// assumes that P has at least 4 points, and all points are in general position
Convex_Hull_3d(const Points& P) :
map_facets(hash_map<edge, triangle_ptr>(6*P.size())),
convex_hull(hash_map<tri, bool>(6*P.size())),
Expand Down Expand Up @@ -170,7 +168,6 @@ struct Convex_Hull_3d {
{t[1], t[2], edge{2, 3}},
{t[1], t[3], edge{1, 3}},
{t[2], t[3], edge{0, 3}}};
for (auto& x : t) x = nullptr; // allow to be reclaimed

parlay::parallel_for(0, 6, [&](auto i) {
auto [t1, t2, e] = ridges[i];
Expand Down
2 changes: 2 additions & 0 deletions include/parlay/alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#include "type_traits.h" // IWYU pragma: keep
#include "utilities.h"

//#define UseHugepages 1

#include "internal/block_allocator.h"
#include "internal/memory_size.h"
#include "internal/pool_allocator.h"
Expand Down
21 changes: 19 additions & 2 deletions include/parlay/internal/block_allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@

#include "memory_size.h"

#ifdef UseHugepages
#include <sys/mman.h>
#endif

// IWYU pragma: no_include <array>
// IWYU pragma: no_include <vector>

Expand All @@ -39,7 +43,13 @@ namespace internal {
struct block_allocator {
private:

static inline constexpr size_t default_list_bytes = (1 << 18) - 64; // in bytes
#ifdef UseHugepages
static inline constexpr size_t huge_page_size = (1ul << 21);
static inline constexpr size_t default_list_bytes = huge_page_size - 64; // in bytes
#else
static inline constexpr size_t default_list_bytes = (1ul << 18) - 64; // in bytes
#endif

static inline constexpr size_t min_alignment = 128; // for cache line padding

struct block {
Expand Down Expand Up @@ -98,7 +108,14 @@ struct block_allocator {
}

auto allocate_blocks(size_t num_blocks) -> std::byte* {
auto buffer = static_cast<std::byte*>(::operator new(num_blocks * block_size, block_align));
long total_bytes = num_blocks * block_size;
#ifdef UseHugepages
auto buffer = static_cast<std::byte*>(::operator new(total_bytes, std::align_val_t{huge_page_size}));
madvise(buffer, total_bytes, MADV_HUGEPAGE);
#else
auto buffer = static_cast<std::byte*>(::operator new(total_bytes, block_align));
#endif

assert(buffer != nullptr);

blocks_allocated.fetch_add(num_blocks);
Expand Down
20 changes: 17 additions & 3 deletions include/parlay/internal/pool_allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@

#include "concurrency/hazptr_stack.h"

#ifdef UseHugepages
#include <sys/mman.h>
#endif

// IWYU pragma: no_include <array>

namespace parlay {
Expand All @@ -42,6 +46,7 @@ namespace internal {
struct pool_allocator {

// Maximum alignment guaranteed by the allocator
#
static inline constexpr size_t max_alignment = 128;

private:
Expand Down Expand Up @@ -73,11 +78,20 @@ struct pool_allocator {

// Alloc size must be a multiple of the alignment
// Round up to the next multiple.
if (alloc_size % max_alignment != 0) {
alloc_size += (max_alignment - (alloc_size % max_alignment));
#ifdef UseHugepages
unsigned long alignment = 1ul << 21;
#else
unsigned long alignment = max_alignment;
#endif

if (alloc_size % alignment != 0) {
alloc_size += (alignment - (alloc_size % alignment));
}

void* a = ::operator new(alloc_size, std::align_val_t{max_alignment});
void* a = ::operator new(alloc_size, std::align_val_t{alignment});
#ifdef UseHugepages
madvise(a, alloc_size, MADV_HUGEPAGE);
#endif

large_allocated += n;
return a;
Expand Down

0 comments on commit 1f05a2f

Please sign in to comment.