haikuwebkit/PerformanceTests/MallocBench/MallocBench/stress_aligned.cpp

199 lines
5.4 KiB
C++
Raw Permalink Normal View History

bmalloc: support aligned allocation https://bugs.webkit.org/show_bug.cgi?id=140732 Reviewed by Andreas Kling. PerformanceTests: * MallocBench/MallocBench.xcodeproj/project.pbxproj: * MallocBench/MallocBench/Benchmark.cpp: * MallocBench/MallocBench/memalign.cpp: (test): (benchmark_memalign): Added a test for specific interesting memalign values. * MallocBench/MallocBench/stress_aligned.cpp: Added. (benchmark_stress_aligned): * MallocBench/MallocBench/stress_aligned.h: Added. Added a stress test for arbitrary memalign values. Source/bmalloc: * bmalloc/Allocator.cpp: (bmalloc::Allocator::allocate): New function for aligned allocation. Small and medium requests just allocate and free until they find an aligned pointer. This is slightly inefficient in the worst case, but still constant-time with little-to-no space overhead. Large requests use a new API that requires the client to specify both its ideal size and alignment, and the worst-case size you would have to allocate in order to produce some interior pointer of the requested size and alignment. We put the burden of this calculation on the client because it simplifies things if we guarantee that allocation won't fail. XLarge requests are easy: we just forward them to vmAllocate, which already supported aligned requests. * bmalloc/BoundaryTag.h: * bmalloc/BoundaryTagInlines.h: (bmalloc::BoundaryTag::mergeLeft): (bmalloc::BoundaryTag::mergeRight): (bmalloc::BoundaryTag::merge): (bmalloc::BoundaryTag::deallocate): (bmalloc::BoundaryTag::split): (bmalloc::BoundaryTag::allocate): No behavior change here. I just refactored the interface to remove some reference out parameters in order to clarify what changes and what doesn't. * bmalloc/Heap.cpp: (bmalloc::Heap::allocateXLarge): Added an alignment API. (bmalloc::Heap::allocateLarge): * bmalloc/Heap.h: Added an alignment API. I split out allocateLarge into a few variants, so aligned and unaligned allocation could share some code. * bmalloc/SegregatedFreeList.cpp: (bmalloc::SegregatedFreeList::take): * bmalloc/SegregatedFreeList.h: Changed to use a separate, explicit API for aligned allocation. It turns out that the aligned path is pretty different, since it ends up searching for two potential ways to satisfy an allocation: either large enough and aligned, or large enough to split into something not aligned and something large enough and aligned. * bmalloc/VMAllocate.h: (bmalloc::vmAllocate): Switched alignment to come before size because that's how the memalign API specifies it. * bmalloc/VMHeap.h: (bmalloc::VMHeap::allocateLargeRange): Added an alignment API. Canonical link: https://commits.webkit.org/158719@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@178861 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-01-21 22:49:45 +00:00
/*
* Copyright (C) 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "Benchmark.h"
#include "CPUCount.h"
#include "stress_aligned.h"
#include <array>
[Linux] Port MallocBench https://bugs.webkit.org/show_bug.cgi?id=177856 Reviewed by Filip Pizlo. .: * CMakeLists.txt: PerformanceTests: We would like to optimize locking in bmalloc in Linux by using futex APIs. So we should have the way to ensure this actually improves / does not regress the performance. This patch ports MallocBench to Linux to measure/ensure the effect of bmalloc patch in Linux. While we replace the dispatch serial queue in message.cpp, we still use libdispatch in Benchmark.cpp since we do not have priority mechanism in C++11 threading implementation. We also extend run-malloc-benchmarks to accept cmake style layout of build product directory. And we also support building MallocBench in CMake environment including CMake Mac ports. Currently, we do not support Windows yet. Based on the measurement, we can say the following observation. glibc's malloc performance is not so bad. While bmalloc shows 3.8x (in geomean) performance improvement, bmalloc in Linux shows 2.0x improvement. Since both numbers in bmalloc are similar, we can think that bmalloc's optimization is actually working in Linux too. And even though glibc's malloc perofmrnace is not so bad, bmalloc still offers performance improvement. * CMakeLists.txt: Added. * MallocBench/CMakeLists.txt: Added. * MallocBench/MallocBench.xcodeproj/project.pbxproj: * MallocBench/MallocBench/Benchmark.cpp: (Benchmark::Benchmark): (Benchmark::runOnce): (Benchmark::currentMemoryBytes): Deleted. * MallocBench/MallocBench/Benchmark.h: (Benchmark::Memory::Memory): Deleted. (Benchmark::Memory::operator-): Deleted. * MallocBench/MallocBench/CMakeLists.txt: Added. * MallocBench/MallocBench/CPUCount.cpp: (cpuCount): * MallocBench/MallocBench/Interpreter.cpp: (Interpreter::doMallocOp): * MallocBench/MallocBench/Memory.cpp: Added. (currentMemoryBytes): * MallocBench/MallocBench/Memory.h: Copied from PerformanceTests/MallocBench/MallocBench/CPUCount.cpp. (Memory::Memory): (Memory::operator-): * MallocBench/MallocBench/balloon.cpp: (benchmark_balloon): * MallocBench/MallocBench/mbmalloc.cpp: * MallocBench/MallocBench/message.cpp: (WorkQueue::WorkQueue): (WorkQueue::~WorkQueue): (WorkQueue::dispatchAsync): (WorkQueue::dispatchSync): (benchmark_message_one): (benchmark_message_many): * MallocBench/MallocBench/nimlang.cpp: (benchmark_nimlang): * MallocBench/MallocBench/stress.cpp: (SizeStream::next): * MallocBench/MallocBench/stress_aligned.cpp: * MallocBench/run-malloc-benchmarks: Source/bmalloc: * CMakeLists.txt: Canonical link: https://commits.webkit.org/194175@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@222900 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-05 07:05:44 +00:00
#include <cassert>
bmalloc: support aligned allocation https://bugs.webkit.org/show_bug.cgi?id=140732 Reviewed by Andreas Kling. PerformanceTests: * MallocBench/MallocBench.xcodeproj/project.pbxproj: * MallocBench/MallocBench/Benchmark.cpp: * MallocBench/MallocBench/memalign.cpp: (test): (benchmark_memalign): Added a test for specific interesting memalign values. * MallocBench/MallocBench/stress_aligned.cpp: Added. (benchmark_stress_aligned): * MallocBench/MallocBench/stress_aligned.h: Added. Added a stress test for arbitrary memalign values. Source/bmalloc: * bmalloc/Allocator.cpp: (bmalloc::Allocator::allocate): New function for aligned allocation. Small and medium requests just allocate and free until they find an aligned pointer. This is slightly inefficient in the worst case, but still constant-time with little-to-no space overhead. Large requests use a new API that requires the client to specify both its ideal size and alignment, and the worst-case size you would have to allocate in order to produce some interior pointer of the requested size and alignment. We put the burden of this calculation on the client because it simplifies things if we guarantee that allocation won't fail. XLarge requests are easy: we just forward them to vmAllocate, which already supported aligned requests. * bmalloc/BoundaryTag.h: * bmalloc/BoundaryTagInlines.h: (bmalloc::BoundaryTag::mergeLeft): (bmalloc::BoundaryTag::mergeRight): (bmalloc::BoundaryTag::merge): (bmalloc::BoundaryTag::deallocate): (bmalloc::BoundaryTag::split): (bmalloc::BoundaryTag::allocate): No behavior change here. I just refactored the interface to remove some reference out parameters in order to clarify what changes and what doesn't. * bmalloc/Heap.cpp: (bmalloc::Heap::allocateXLarge): Added an alignment API. (bmalloc::Heap::allocateLarge): * bmalloc/Heap.h: Added an alignment API. I split out allocateLarge into a few variants, so aligned and unaligned allocation could share some code. * bmalloc/SegregatedFreeList.cpp: (bmalloc::SegregatedFreeList::take): * bmalloc/SegregatedFreeList.h: Changed to use a separate, explicit API for aligned allocation. It turns out that the aligned path is pretty different, since it ends up searching for two potential ways to satisfy an allocation: either large enough and aligned, or large enough to split into something not aligned and something large enough and aligned. * bmalloc/VMAllocate.h: (bmalloc::vmAllocate): Switched alignment to come before size because that's how the memalign API specifies it. * bmalloc/VMHeap.h: (bmalloc::VMHeap::allocateLargeRange): Added an alignment API. Canonical link: https://commits.webkit.org/158719@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@178861 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-01-21 22:49:45 +00:00
#include <chrono>
#include <cmath>
#include <cstdlib>
#include <memory>
#include <stddef.h>
#include <vector>
#include "mbmalloc.h"
namespace {
static const size_t kB = 1024;
static const size_t MB = kB * kB;
struct Object {
Object(void* pointer, size_t size, long uuid)
: pointer(pointer)
, size(size)
, uuid(uuid)
{
}
void* pointer;
size_t size;
long uuid;
};
class SizeStream {
public:
SizeStream()
: m_state(Small)
, m_count(0)
{
}
size_t next()
{
switch (m_state) {
case Small: {
if (++m_count == smallCount) {
m_state = Medium;
m_count = 0;
}
return random() % smallMax;
}
case Medium: {
if (++m_count == mediumCount) {
m_state = Large;
m_count = 0;
}
return random() % mediumMax;
}
case Large: {
if (++m_count == largeCount) {
m_state = Small;
m_count = 0;
}
return random() % largeMax;
}
}
[Linux] Port MallocBench https://bugs.webkit.org/show_bug.cgi?id=177856 Reviewed by Filip Pizlo. .: * CMakeLists.txt: PerformanceTests: We would like to optimize locking in bmalloc in Linux by using futex APIs. So we should have the way to ensure this actually improves / does not regress the performance. This patch ports MallocBench to Linux to measure/ensure the effect of bmalloc patch in Linux. While we replace the dispatch serial queue in message.cpp, we still use libdispatch in Benchmark.cpp since we do not have priority mechanism in C++11 threading implementation. We also extend run-malloc-benchmarks to accept cmake style layout of build product directory. And we also support building MallocBench in CMake environment including CMake Mac ports. Currently, we do not support Windows yet. Based on the measurement, we can say the following observation. glibc's malloc performance is not so bad. While bmalloc shows 3.8x (in geomean) performance improvement, bmalloc in Linux shows 2.0x improvement. Since both numbers in bmalloc are similar, we can think that bmalloc's optimization is actually working in Linux too. And even though glibc's malloc perofmrnace is not so bad, bmalloc still offers performance improvement. * CMakeLists.txt: Added. * MallocBench/CMakeLists.txt: Added. * MallocBench/MallocBench.xcodeproj/project.pbxproj: * MallocBench/MallocBench/Benchmark.cpp: (Benchmark::Benchmark): (Benchmark::runOnce): (Benchmark::currentMemoryBytes): Deleted. * MallocBench/MallocBench/Benchmark.h: (Benchmark::Memory::Memory): Deleted. (Benchmark::Memory::operator-): Deleted. * MallocBench/MallocBench/CMakeLists.txt: Added. * MallocBench/MallocBench/CPUCount.cpp: (cpuCount): * MallocBench/MallocBench/Interpreter.cpp: (Interpreter::doMallocOp): * MallocBench/MallocBench/Memory.cpp: Added. (currentMemoryBytes): * MallocBench/MallocBench/Memory.h: Copied from PerformanceTests/MallocBench/MallocBench/CPUCount.cpp. (Memory::Memory): (Memory::operator-): * MallocBench/MallocBench/balloon.cpp: (benchmark_balloon): * MallocBench/MallocBench/mbmalloc.cpp: * MallocBench/MallocBench/message.cpp: (WorkQueue::WorkQueue): (WorkQueue::~WorkQueue): (WorkQueue::dispatchAsync): (WorkQueue::dispatchSync): (benchmark_message_one): (benchmark_message_many): * MallocBench/MallocBench/nimlang.cpp: (benchmark_nimlang): * MallocBench/MallocBench/stress.cpp: (SizeStream::next): * MallocBench/MallocBench/stress_aligned.cpp: * MallocBench/run-malloc-benchmarks: Source/bmalloc: * CMakeLists.txt: Canonical link: https://commits.webkit.org/194175@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@222900 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-05 07:05:44 +00:00
assert(0);
return 0;
bmalloc: support aligned allocation https://bugs.webkit.org/show_bug.cgi?id=140732 Reviewed by Andreas Kling. PerformanceTests: * MallocBench/MallocBench.xcodeproj/project.pbxproj: * MallocBench/MallocBench/Benchmark.cpp: * MallocBench/MallocBench/memalign.cpp: (test): (benchmark_memalign): Added a test for specific interesting memalign values. * MallocBench/MallocBench/stress_aligned.cpp: Added. (benchmark_stress_aligned): * MallocBench/MallocBench/stress_aligned.h: Added. Added a stress test for arbitrary memalign values. Source/bmalloc: * bmalloc/Allocator.cpp: (bmalloc::Allocator::allocate): New function for aligned allocation. Small and medium requests just allocate and free until they find an aligned pointer. This is slightly inefficient in the worst case, but still constant-time with little-to-no space overhead. Large requests use a new API that requires the client to specify both its ideal size and alignment, and the worst-case size you would have to allocate in order to produce some interior pointer of the requested size and alignment. We put the burden of this calculation on the client because it simplifies things if we guarantee that allocation won't fail. XLarge requests are easy: we just forward them to vmAllocate, which already supported aligned requests. * bmalloc/BoundaryTag.h: * bmalloc/BoundaryTagInlines.h: (bmalloc::BoundaryTag::mergeLeft): (bmalloc::BoundaryTag::mergeRight): (bmalloc::BoundaryTag::merge): (bmalloc::BoundaryTag::deallocate): (bmalloc::BoundaryTag::split): (bmalloc::BoundaryTag::allocate): No behavior change here. I just refactored the interface to remove some reference out parameters in order to clarify what changes and what doesn't. * bmalloc/Heap.cpp: (bmalloc::Heap::allocateXLarge): Added an alignment API. (bmalloc::Heap::allocateLarge): * bmalloc/Heap.h: Added an alignment API. I split out allocateLarge into a few variants, so aligned and unaligned allocation could share some code. * bmalloc/SegregatedFreeList.cpp: (bmalloc::SegregatedFreeList::take): * bmalloc/SegregatedFreeList.h: Changed to use a separate, explicit API for aligned allocation. It turns out that the aligned path is pretty different, since it ends up searching for two potential ways to satisfy an allocation: either large enough and aligned, or large enough to split into something not aligned and something large enough and aligned. * bmalloc/VMAllocate.h: (bmalloc::vmAllocate): Switched alignment to come before size because that's how the memalign API specifies it. * bmalloc/VMHeap.h: (bmalloc::VMHeap::allocateLargeRange): Added an alignment API. Canonical link: https://commits.webkit.org/158719@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@178861 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-01-21 22:49:45 +00:00
}
private:
static const size_t smallCount = 1000;
static const size_t smallMax = 16 * kB;
static const size_t mediumCount = 100;
static const size_t mediumMax = 512 * kB;
static const size_t largeCount = 10;
static const size_t largeMax = 4 * MB;
enum { Small, Medium, Large } m_state;
size_t m_count;
};
Object allocate(size_t alignment, size_t size)
{
Object object(mbmemalign(alignment, size), size, random());
if ((uintptr_t)object.pointer & (alignment - 1))
abort();
for (size_t i = 0; i < size / sizeof(long); ++i)
(static_cast<long*>(object.pointer))[i] = object.uuid;
return object;
}
void deallocate(const Object& object)
{
for (size_t i = 0; i < object.size / sizeof(long); ++i) {
if ((static_cast<long*>(object.pointer))[i] != object.uuid)
abort();
}
mbfree(object.pointer, object.size);
}
size_t randomAlignment()
{
switch (random() % 32) {
case 0:
return pow(2, random() % 26);
default:
return pow(2, random() % 14);
}
}
}
MallocBench: Added recording for nimlang website, new recording details and added new options https://bugs.webkit.org/show_bug.cgi?id=154485 Reviewed by Geoff Garen. Added new capabilities to MallocBench. These include: Added a recording of http://nim-lang.org/docs/lib.html. Added thread id to the recording and the ability to playback switching threads in MallocBench Added aligned allocations to recordings and the ability to playback Added --use-thread-id option to honor recorded thread ids Added --detailed-report to output remaining allocations by size after playback Added --no-warmup to not run the warm up iteration Changed the way that options are passed down to the benchmarks. Instead of passing individual boolean or numeric option values, just pass a reference the CommandLine itself. Each benchmark can access the options that are appropriate. The Benchmark class also uses the options for is parallel, run counts and warm up. Added thread id and aligned malloc to the Op by noticing that structure padding and Opcode allowed for another 32 bits of data. Breaking that unused 32 bits into a 16 bit thread id value and a 16 bit log base 2 of the alignment for aligned malloc allowed for existing recordings to playback without any incompatibilities. Threaded operation is simulated by creating threads as needed. As long as the next Op's thread id is the same as the last, operation continues as normal. When the next Op has a different thread id, we switch to that thread using the shared Op stream to continue playing back. There is a mutex to assure that only one thread is really running at a time and a condition variable used to wait that the current thread id matches each block thread's thread id. This doesn't simulate true concurrent threading, but is instead plays back Ops recorded for multiple thread faithfully. * MallocBench/MallocBench.xcodeproj/project.pbxproj: * MallocBench/MallocBench/Benchmark.cpp: (deallocateHeap): (Benchmark::Benchmark): (Benchmark::runOnce): (Benchmark::run): * MallocBench/MallocBench/Benchmark.h: (Benchmark::isValid): * MallocBench/MallocBench/CommandLine.cpp: (CommandLine::printUsage): * MallocBench/MallocBench/CommandLine.h: (CommandLine::isValid): (CommandLine::benchmarkName): (CommandLine::isParallel): (CommandLine::useThreadID): (CommandLine::detailedReport): (CommandLine::warmUp): (CommandLine::heapSize): (CommandLine::runs): * MallocBench/MallocBench/Interpreter.cpp: (Interpreter::Interpreter): (Interpreter::run): (Interpreter::readOps): (Interpreter::doOnSameThread): (Interpreter::switchToThread): (Interpreter::detailedReport): (compute2toPower): (writeData): (Interpreter::doMallocOp): (Interpreter::Thread::Thread): (Interpreter::Thread::stop): (Interpreter::Thread::~Thread): (Interpreter::Thread::runThread): (Interpreter::Thread::waitToRun): (Interpreter::Thread::switchTo): * MallocBench/MallocBench/Interpreter.h: (Interpreter::Thread::isMainThread): * MallocBench/MallocBench/alloc_free.cpp: Added. (benchmark_alloc_free): * MallocBench/MallocBench/alloc_free.h: Added. * MallocBench/MallocBench/balloon.cpp: (benchmark_balloon): * MallocBench/MallocBench/balloon.h: * MallocBench/MallocBench/big.cpp: (benchmark_big): * MallocBench/MallocBench/big.h: * MallocBench/MallocBench/churn.cpp: (benchmark_churn): * MallocBench/MallocBench/churn.h: * MallocBench/MallocBench/facebook.cpp: (benchmark_facebook): * MallocBench/MallocBench/facebook.h: * MallocBench/MallocBench/flickr.cpp: (benchmark_flickr): (benchmark_flickr_memory_warning): * MallocBench/MallocBench/flickr.h: * MallocBench/MallocBench/fragment.cpp: (validate): (benchmark_fragment): (benchmark_fragment_iterate): * MallocBench/MallocBench/fragment.h: * MallocBench/MallocBench/list.cpp: (benchmark_list_allocate): (benchmark_list_traverse): * MallocBench/MallocBench/list.h: * MallocBench/MallocBench/main.cpp: (main): * MallocBench/MallocBench/medium.cpp: (benchmark_medium): * MallocBench/MallocBench/medium.h: * MallocBench/MallocBench/memalign.cpp: (test): (benchmark_memalign): * MallocBench/MallocBench/memalign.h: * MallocBench/MallocBench/message.cpp: (benchmark_message_one): (benchmark_message_many): * MallocBench/MallocBench/message.h: * MallocBench/MallocBench/nimlang.cpp: Added. (benchmark_nimlang): * MallocBench/MallocBench/nimlang.h: Added. * MallocBench/MallocBench/nimlang.ops: Added. * MallocBench/MallocBench/realloc.cpp: (benchmark_realloc): * MallocBench/MallocBench/realloc.h: * MallocBench/MallocBench/reddit.cpp: (benchmark_reddit): (benchmark_reddit_memory_warning): * MallocBench/MallocBench/reddit.h: * MallocBench/MallocBench/stress.cpp: (deallocate): (benchmark_stress): * MallocBench/MallocBench/stress.h: * MallocBench/MallocBench/stress_aligned.cpp: (benchmark_stress_aligned): * MallocBench/MallocBench/stress_aligned.h: * MallocBench/MallocBench/theverge.cpp: (benchmark_theverge): (benchmark_theverge_memory_warning): * MallocBench/MallocBench/theverge.h: * MallocBench/MallocBench/tree.cpp: (benchmark_tree_allocate): (benchmark_tree_traverse): (benchmark_tree_churn): * MallocBench/MallocBench/tree.h: * MallocBench/run-malloc-benchmarks: Canonical link: https://commits.webkit.org/172661@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@196955 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-02-22 22:02:24 +00:00
void benchmark_stress_aligned(CommandLine&)
bmalloc: support aligned allocation https://bugs.webkit.org/show_bug.cgi?id=140732 Reviewed by Andreas Kling. PerformanceTests: * MallocBench/MallocBench.xcodeproj/project.pbxproj: * MallocBench/MallocBench/Benchmark.cpp: * MallocBench/MallocBench/memalign.cpp: (test): (benchmark_memalign): Added a test for specific interesting memalign values. * MallocBench/MallocBench/stress_aligned.cpp: Added. (benchmark_stress_aligned): * MallocBench/MallocBench/stress_aligned.h: Added. Added a stress test for arbitrary memalign values. Source/bmalloc: * bmalloc/Allocator.cpp: (bmalloc::Allocator::allocate): New function for aligned allocation. Small and medium requests just allocate and free until they find an aligned pointer. This is slightly inefficient in the worst case, but still constant-time with little-to-no space overhead. Large requests use a new API that requires the client to specify both its ideal size and alignment, and the worst-case size you would have to allocate in order to produce some interior pointer of the requested size and alignment. We put the burden of this calculation on the client because it simplifies things if we guarantee that allocation won't fail. XLarge requests are easy: we just forward them to vmAllocate, which already supported aligned requests. * bmalloc/BoundaryTag.h: * bmalloc/BoundaryTagInlines.h: (bmalloc::BoundaryTag::mergeLeft): (bmalloc::BoundaryTag::mergeRight): (bmalloc::BoundaryTag::merge): (bmalloc::BoundaryTag::deallocate): (bmalloc::BoundaryTag::split): (bmalloc::BoundaryTag::allocate): No behavior change here. I just refactored the interface to remove some reference out parameters in order to clarify what changes and what doesn't. * bmalloc/Heap.cpp: (bmalloc::Heap::allocateXLarge): Added an alignment API. (bmalloc::Heap::allocateLarge): * bmalloc/Heap.h: Added an alignment API. I split out allocateLarge into a few variants, so aligned and unaligned allocation could share some code. * bmalloc/SegregatedFreeList.cpp: (bmalloc::SegregatedFreeList::take): * bmalloc/SegregatedFreeList.h: Changed to use a separate, explicit API for aligned allocation. It turns out that the aligned path is pretty different, since it ends up searching for two potential ways to satisfy an allocation: either large enough and aligned, or large enough to split into something not aligned and something large enough and aligned. * bmalloc/VMAllocate.h: (bmalloc::vmAllocate): Switched alignment to come before size because that's how the memalign API specifies it. * bmalloc/VMHeap.h: (bmalloc::VMHeap::allocateLargeRange): Added an alignment API. Canonical link: https://commits.webkit.org/158719@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@178861 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-01-21 22:49:45 +00:00
{
const size_t heapSize = 100 * MB;
const size_t churnSize = .05 * heapSize;
const size_t churnCount = 100;
srandom(1); // For consistency between runs.
bmalloc: Misc improvements to MallocBench https://bugs.webkit.org/show_bug.cgi?id=157004 Reviewed by Darin Adler. * MallocBench/run-malloc-benchmarks: Added --memory and --memory_warning modes for focused memory testing. * MallocBench/MallocBench/Benchmark.cpp: (Benchmark::printReport): Clarified output. (Benchmark::currentMemoryBytes): Added compressed memory because top does the same. (It always happens to zero in the benchmarks we run. But this is good for sanity.) * MallocBench/MallocBench/CommandLine.cpp: Moved up to 8 runs to reduce variance. * MallocBench/MallocBench/alloc_free.cpp: (benchmark_alloc_free): Cycle a single allocation in order to stress the effect of merging on calls to madvise. * MallocBench/MallocBench/big.cpp: (benchmark_big): Graduated to 8kB-128kB because medium tests up to 8 and our large allocator doesn't kick in until 64kB. * MallocBench/MallocBench/medium.cpp: (benchmark_medium): Test all the way down to 1kB because our large allocator used to service 1kB allocations and 1kB is an interesting middle size where memory is unusually large but allocation throughput still matters. * MallocBench/MallocBench/stress.cpp: (benchmark_stress): Reduced the churn count to match stress_aligned because this test was taking too long to complete. * MallocBench/MallocBench/stress_aligned.cpp: (benchmark_stress_aligned): Our new large allocator can handle even more absurdly large values. Canonical link: https://commits.webkit.org/175116@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@200060 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-04-25 23:50:25 +00:00
size_t limit = 0x00001ffffffffffful;
for (size_t size = 0; size < limit; size = std::max(size, sizeof(void*)) * 2) {
for (size_t alignment = sizeof(void*); alignment < limit; alignment *= 2) {
void* object = mbmemalign(alignment, size);
if (reinterpret_cast<uintptr_t>(object) & (alignment - 1))
abort();
mbfree(object, size);
}
bmalloc: Misc improvements to MallocBench https://bugs.webkit.org/show_bug.cgi?id=157004 Reviewed by Darin Adler. * MallocBench/run-malloc-benchmarks: Added --memory and --memory_warning modes for focused memory testing. * MallocBench/MallocBench/Benchmark.cpp: (Benchmark::printReport): Clarified output. (Benchmark::currentMemoryBytes): Added compressed memory because top does the same. (It always happens to zero in the benchmarks we run. But this is good for sanity.) * MallocBench/MallocBench/CommandLine.cpp: Moved up to 8 runs to reduce variance. * MallocBench/MallocBench/alloc_free.cpp: (benchmark_alloc_free): Cycle a single allocation in order to stress the effect of merging on calls to madvise. * MallocBench/MallocBench/big.cpp: (benchmark_big): Graduated to 8kB-128kB because medium tests up to 8 and our large allocator doesn't kick in until 64kB. * MallocBench/MallocBench/medium.cpp: (benchmark_medium): Test all the way down to 1kB because our large allocator used to service 1kB allocations and 1kB is an interesting middle size where memory is unusually large but allocation throughput still matters. * MallocBench/MallocBench/stress.cpp: (benchmark_stress): Reduced the churn count to match stress_aligned because this test was taking too long to complete. * MallocBench/MallocBench/stress_aligned.cpp: (benchmark_stress_aligned): Our new large allocator can handle even more absurdly large values. Canonical link: https://commits.webkit.org/175116@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@200060 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-04-25 23:50:25 +00:00
for (size_t alignment = sizeof(void*); alignment < limit; alignment *= 2) {
void* object = mbmemalign(alignment, size + 128);
if (reinterpret_cast<uintptr_t>(object) & (alignment - 1))
abort();
mbfree(object, size + 128);
}
}
bmalloc: support aligned allocation https://bugs.webkit.org/show_bug.cgi?id=140732 Reviewed by Andreas Kling. PerformanceTests: * MallocBench/MallocBench.xcodeproj/project.pbxproj: * MallocBench/MallocBench/Benchmark.cpp: * MallocBench/MallocBench/memalign.cpp: (test): (benchmark_memalign): Added a test for specific interesting memalign values. * MallocBench/MallocBench/stress_aligned.cpp: Added. (benchmark_stress_aligned): * MallocBench/MallocBench/stress_aligned.h: Added. Added a stress test for arbitrary memalign values. Source/bmalloc: * bmalloc/Allocator.cpp: (bmalloc::Allocator::allocate): New function for aligned allocation. Small and medium requests just allocate and free until they find an aligned pointer. This is slightly inefficient in the worst case, but still constant-time with little-to-no space overhead. Large requests use a new API that requires the client to specify both its ideal size and alignment, and the worst-case size you would have to allocate in order to produce some interior pointer of the requested size and alignment. We put the burden of this calculation on the client because it simplifies things if we guarantee that allocation won't fail. XLarge requests are easy: we just forward them to vmAllocate, which already supported aligned requests. * bmalloc/BoundaryTag.h: * bmalloc/BoundaryTagInlines.h: (bmalloc::BoundaryTag::mergeLeft): (bmalloc::BoundaryTag::mergeRight): (bmalloc::BoundaryTag::merge): (bmalloc::BoundaryTag::deallocate): (bmalloc::BoundaryTag::split): (bmalloc::BoundaryTag::allocate): No behavior change here. I just refactored the interface to remove some reference out parameters in order to clarify what changes and what doesn't. * bmalloc/Heap.cpp: (bmalloc::Heap::allocateXLarge): Added an alignment API. (bmalloc::Heap::allocateLarge): * bmalloc/Heap.h: Added an alignment API. I split out allocateLarge into a few variants, so aligned and unaligned allocation could share some code. * bmalloc/SegregatedFreeList.cpp: (bmalloc::SegregatedFreeList::take): * bmalloc/SegregatedFreeList.h: Changed to use a separate, explicit API for aligned allocation. It turns out that the aligned path is pretty different, since it ends up searching for two potential ways to satisfy an allocation: either large enough and aligned, or large enough to split into something not aligned and something large enough and aligned. * bmalloc/VMAllocate.h: (bmalloc::vmAllocate): Switched alignment to come before size because that's how the memalign API specifies it. * bmalloc/VMHeap.h: (bmalloc::VMHeap::allocateLargeRange): Added an alignment API. Canonical link: https://commits.webkit.org/158719@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@178861 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-01-21 22:49:45 +00:00
std::vector<Object> objects;
SizeStream sizeStream;
size_t size = 0;
for (size_t remaining = heapSize; remaining; remaining -= std::min(remaining, size)) {
size = sizeStream.next();
objects.push_back(allocate(randomAlignment(), size));
}
for (size_t i = 0; i < churnCount; ++i) {
std::vector<Object> objectsToFree;
for (size_t remaining = churnSize; remaining; remaining -= std::min(remaining, size)) {
size = sizeStream.next();
Object object = allocate(randomAlignment(), size);
size_t index = random() % objects.size();
objectsToFree.push_back(objects[index]);
objects[index] = object;
}
for (auto& object : objectsToFree)
deallocate(object);
mbscavenge();
}
for (auto& object : objects)
mbfree(object.pointer, object.size);
}