dawn-cmake/src/block_allocator_test.cc

148 lines
3.4 KiB
C++
Raw Normal View History

// Copyright 2021 The Tint Authors.
//
// Licensed 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.
#include "src/block_allocator.h"
#include "gtest/gtest.h"
namespace tint {
namespace {
struct LifetimeCounter {
explicit LifetimeCounter(size_t* count) : count_(count) { (*count)++; }
~LifetimeCounter() { (*count_)--; }
size_t* const count_;
};
using BlockAllocatorTest = testing::Test;
TEST_F(BlockAllocatorTest, Empty) {
using Allocator = BlockAllocator<int>;
Allocator allocator;
for (int* i : allocator.Objects()) {
(void)i;
if ((true)) { // Workaround for "error: loop will run at most once"
FAIL() << "BlockAllocator should be empty";
}
}
optimization: BlockAllocator: Actually allocate in blocks Instead of hitting the heap for each and every call to Create() Significantly improves performance for heavy loads. Slight performance loss for lighter loads. A: base.bench B: new.bench Test name | Δ (A → B) | % (A → B) --------------------------------------+--------------+----------- GenerateSPIRV/"simple_fragment.wgsl" | 27.021µs | +6.4% GenerateMSL/"simple_compute.wgsl" | 35.592µs | +6.1% GenerateMSL/"simple_vertex.wgsl" | 37.64µs | +5.5% GenerateHLSL/"simple_fragment.wgsl" | 42.145µs | +5.2% GenerateGLSL/"simple_fragment.wgsl" | 31.506µs | +4.9% GenerateHLSL/"simple_vertex.wgsl" | 38.843µs | +4.7% GenerateMSL/"simple_fragment.wgsl" | 29.977µs | +4.5% GenerateSPIRV/"simple_vertex.wgsl" | 19.882µs | +4.2% GenerateGLSL/"simple_vertex.wgsl" | 24.702µs | +3.7% GenerateSPIRV/"simple_compute.wgsl" | 17.652µs | +3.2% GenerateHLSL/"simple_compute.wgsl" | 26.826µs | +2.7% GenerateGLSL/"simple_compute.wgsl" | 11.952µs | +1.8% ParseWGSL/"particles.wgsl" | -104.83µs | -4.2% GenerateMSL/"particles.wgsl" | -1.079243ms | -9.4% GenerateSPIRV/"particles.wgsl" | -1.012483ms | -9.4% GenerateGLSL/"particles.wgsl" | -3.522106ms | -9.5% GenerateHLSL/"particles.wgsl" | -1.849666ms | -10.6% Issue: tint:1383 Change-Id: Ib691328538c597c06a75dfba392c99d2afbd5442 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/76961 Reviewed-by: Antonio Maiorano <amaiorano@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Ben Clayton <bclayton@google.com>
2022-01-22 20:32:38 +00:00
for (const int* i : static_cast<const Allocator&>(allocator).Objects()) {
(void)i;
if ((true)) { // Workaround for "error: loop will run at most once"
FAIL() << "BlockAllocator should be empty";
}
}
}
TEST_F(BlockAllocatorTest, ObjectLifetime) {
using Allocator = BlockAllocator<LifetimeCounter>;
size_t count = 0;
{
Allocator allocator;
EXPECT_EQ(count, 0u);
allocator.Create(&count);
EXPECT_EQ(count, 1u);
allocator.Create(&count);
EXPECT_EQ(count, 2u);
allocator.Create(&count);
EXPECT_EQ(count, 3u);
}
EXPECT_EQ(count, 0u);
}
TEST_F(BlockAllocatorTest, MoveConstruct) {
using Allocator = BlockAllocator<LifetimeCounter>;
optimization: BlockAllocator: Actually allocate in blocks Instead of hitting the heap for each and every call to Create() Significantly improves performance for heavy loads. Slight performance loss for lighter loads. A: base.bench B: new.bench Test name | Δ (A → B) | % (A → B) --------------------------------------+--------------+----------- GenerateSPIRV/"simple_fragment.wgsl" | 27.021µs | +6.4% GenerateMSL/"simple_compute.wgsl" | 35.592µs | +6.1% GenerateMSL/"simple_vertex.wgsl" | 37.64µs | +5.5% GenerateHLSL/"simple_fragment.wgsl" | 42.145µs | +5.2% GenerateGLSL/"simple_fragment.wgsl" | 31.506µs | +4.9% GenerateHLSL/"simple_vertex.wgsl" | 38.843µs | +4.7% GenerateMSL/"simple_fragment.wgsl" | 29.977µs | +4.5% GenerateSPIRV/"simple_vertex.wgsl" | 19.882µs | +4.2% GenerateGLSL/"simple_vertex.wgsl" | 24.702µs | +3.7% GenerateSPIRV/"simple_compute.wgsl" | 17.652µs | +3.2% GenerateHLSL/"simple_compute.wgsl" | 26.826µs | +2.7% GenerateGLSL/"simple_compute.wgsl" | 11.952µs | +1.8% ParseWGSL/"particles.wgsl" | -104.83µs | -4.2% GenerateMSL/"particles.wgsl" | -1.079243ms | -9.4% GenerateSPIRV/"particles.wgsl" | -1.012483ms | -9.4% GenerateGLSL/"particles.wgsl" | -3.522106ms | -9.5% GenerateHLSL/"particles.wgsl" | -1.849666ms | -10.6% Issue: tint:1383 Change-Id: Ib691328538c597c06a75dfba392c99d2afbd5442 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/76961 Reviewed-by: Antonio Maiorano <amaiorano@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Ben Clayton <bclayton@google.com>
2022-01-22 20:32:38 +00:00
for (size_t n :
{0, 1, 10, 16, 20, 32, 50, 64, 100, 256, 300, 512, 500, 512}) {
size_t count = 0;
{
Allocator allocator_a;
for (size_t i = 0; i < n; i++) {
allocator_a.Create(&count);
}
EXPECT_EQ(count, n);
Allocator allocator_b{std::move(allocator_a)};
EXPECT_EQ(count, n);
}
optimization: BlockAllocator: Actually allocate in blocks Instead of hitting the heap for each and every call to Create() Significantly improves performance for heavy loads. Slight performance loss for lighter loads. A: base.bench B: new.bench Test name | Δ (A → B) | % (A → B) --------------------------------------+--------------+----------- GenerateSPIRV/"simple_fragment.wgsl" | 27.021µs | +6.4% GenerateMSL/"simple_compute.wgsl" | 35.592µs | +6.1% GenerateMSL/"simple_vertex.wgsl" | 37.64µs | +5.5% GenerateHLSL/"simple_fragment.wgsl" | 42.145µs | +5.2% GenerateGLSL/"simple_fragment.wgsl" | 31.506µs | +4.9% GenerateHLSL/"simple_vertex.wgsl" | 38.843µs | +4.7% GenerateMSL/"simple_fragment.wgsl" | 29.977µs | +4.5% GenerateSPIRV/"simple_vertex.wgsl" | 19.882µs | +4.2% GenerateGLSL/"simple_vertex.wgsl" | 24.702µs | +3.7% GenerateSPIRV/"simple_compute.wgsl" | 17.652µs | +3.2% GenerateHLSL/"simple_compute.wgsl" | 26.826µs | +2.7% GenerateGLSL/"simple_compute.wgsl" | 11.952µs | +1.8% ParseWGSL/"particles.wgsl" | -104.83µs | -4.2% GenerateMSL/"particles.wgsl" | -1.079243ms | -9.4% GenerateSPIRV/"particles.wgsl" | -1.012483ms | -9.4% GenerateGLSL/"particles.wgsl" | -3.522106ms | -9.5% GenerateHLSL/"particles.wgsl" | -1.849666ms | -10.6% Issue: tint:1383 Change-Id: Ib691328538c597c06a75dfba392c99d2afbd5442 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/76961 Reviewed-by: Antonio Maiorano <amaiorano@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Ben Clayton <bclayton@google.com>
2022-01-22 20:32:38 +00:00
EXPECT_EQ(count, 0u);
}
}
TEST_F(BlockAllocatorTest, MoveAssign) {
using Allocator = BlockAllocator<LifetimeCounter>;
optimization: BlockAllocator: Actually allocate in blocks Instead of hitting the heap for each and every call to Create() Significantly improves performance for heavy loads. Slight performance loss for lighter loads. A: base.bench B: new.bench Test name | Δ (A → B) | % (A → B) --------------------------------------+--------------+----------- GenerateSPIRV/"simple_fragment.wgsl" | 27.021µs | +6.4% GenerateMSL/"simple_compute.wgsl" | 35.592µs | +6.1% GenerateMSL/"simple_vertex.wgsl" | 37.64µs | +5.5% GenerateHLSL/"simple_fragment.wgsl" | 42.145µs | +5.2% GenerateGLSL/"simple_fragment.wgsl" | 31.506µs | +4.9% GenerateHLSL/"simple_vertex.wgsl" | 38.843µs | +4.7% GenerateMSL/"simple_fragment.wgsl" | 29.977µs | +4.5% GenerateSPIRV/"simple_vertex.wgsl" | 19.882µs | +4.2% GenerateGLSL/"simple_vertex.wgsl" | 24.702µs | +3.7% GenerateSPIRV/"simple_compute.wgsl" | 17.652µs | +3.2% GenerateHLSL/"simple_compute.wgsl" | 26.826µs | +2.7% GenerateGLSL/"simple_compute.wgsl" | 11.952µs | +1.8% ParseWGSL/"particles.wgsl" | -104.83µs | -4.2% GenerateMSL/"particles.wgsl" | -1.079243ms | -9.4% GenerateSPIRV/"particles.wgsl" | -1.012483ms | -9.4% GenerateGLSL/"particles.wgsl" | -3.522106ms | -9.5% GenerateHLSL/"particles.wgsl" | -1.849666ms | -10.6% Issue: tint:1383 Change-Id: Ib691328538c597c06a75dfba392c99d2afbd5442 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/76961 Reviewed-by: Antonio Maiorano <amaiorano@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Ben Clayton <bclayton@google.com>
2022-01-22 20:32:38 +00:00
for (size_t n :
{0, 1, 10, 16, 20, 32, 50, 64, 100, 256, 300, 512, 500, 512}) {
size_t count_a = 0;
size_t count_b = 0;
{
Allocator allocator_a;
for (size_t i = 0; i < n; i++) {
allocator_a.Create(&count_a);
}
EXPECT_EQ(count_a, n);
Allocator allocator_b;
for (size_t i = 0; i < n; i++) {
allocator_b.Create(&count_b);
}
EXPECT_EQ(count_b, n);
allocator_b = std::move(allocator_a);
EXPECT_EQ(count_a, n);
EXPECT_EQ(count_b, 0u);
}
optimization: BlockAllocator: Actually allocate in blocks Instead of hitting the heap for each and every call to Create() Significantly improves performance for heavy loads. Slight performance loss for lighter loads. A: base.bench B: new.bench Test name | Δ (A → B) | % (A → B) --------------------------------------+--------------+----------- GenerateSPIRV/"simple_fragment.wgsl" | 27.021µs | +6.4% GenerateMSL/"simple_compute.wgsl" | 35.592µs | +6.1% GenerateMSL/"simple_vertex.wgsl" | 37.64µs | +5.5% GenerateHLSL/"simple_fragment.wgsl" | 42.145µs | +5.2% GenerateGLSL/"simple_fragment.wgsl" | 31.506µs | +4.9% GenerateHLSL/"simple_vertex.wgsl" | 38.843µs | +4.7% GenerateMSL/"simple_fragment.wgsl" | 29.977µs | +4.5% GenerateSPIRV/"simple_vertex.wgsl" | 19.882µs | +4.2% GenerateGLSL/"simple_vertex.wgsl" | 24.702µs | +3.7% GenerateSPIRV/"simple_compute.wgsl" | 17.652µs | +3.2% GenerateHLSL/"simple_compute.wgsl" | 26.826µs | +2.7% GenerateGLSL/"simple_compute.wgsl" | 11.952µs | +1.8% ParseWGSL/"particles.wgsl" | -104.83µs | -4.2% GenerateMSL/"particles.wgsl" | -1.079243ms | -9.4% GenerateSPIRV/"particles.wgsl" | -1.012483ms | -9.4% GenerateGLSL/"particles.wgsl" | -3.522106ms | -9.5% GenerateHLSL/"particles.wgsl" | -1.849666ms | -10.6% Issue: tint:1383 Change-Id: Ib691328538c597c06a75dfba392c99d2afbd5442 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/76961 Reviewed-by: Antonio Maiorano <amaiorano@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Ben Clayton <bclayton@google.com>
2022-01-22 20:32:38 +00:00
EXPECT_EQ(count_a, 0u);
EXPECT_EQ(count_b, 0u);
}
}
TEST_F(BlockAllocatorTest, ObjectOrder) {
using Allocator = BlockAllocator<int>;
Allocator allocator;
constexpr int N = 10000;
for (int i = 0; i < N; i++) {
allocator.Create(i);
}
{
int i = 0;
for (int* p : allocator.Objects()) {
EXPECT_EQ(*p, i);
i++;
}
EXPECT_EQ(i, N);
}
{
int i = 0;
optimization: BlockAllocator: Actually allocate in blocks Instead of hitting the heap for each and every call to Create() Significantly improves performance for heavy loads. Slight performance loss for lighter loads. A: base.bench B: new.bench Test name | Δ (A → B) | % (A → B) --------------------------------------+--------------+----------- GenerateSPIRV/"simple_fragment.wgsl" | 27.021µs | +6.4% GenerateMSL/"simple_compute.wgsl" | 35.592µs | +6.1% GenerateMSL/"simple_vertex.wgsl" | 37.64µs | +5.5% GenerateHLSL/"simple_fragment.wgsl" | 42.145µs | +5.2% GenerateGLSL/"simple_fragment.wgsl" | 31.506µs | +4.9% GenerateHLSL/"simple_vertex.wgsl" | 38.843µs | +4.7% GenerateMSL/"simple_fragment.wgsl" | 29.977µs | +4.5% GenerateSPIRV/"simple_vertex.wgsl" | 19.882µs | +4.2% GenerateGLSL/"simple_vertex.wgsl" | 24.702µs | +3.7% GenerateSPIRV/"simple_compute.wgsl" | 17.652µs | +3.2% GenerateHLSL/"simple_compute.wgsl" | 26.826µs | +2.7% GenerateGLSL/"simple_compute.wgsl" | 11.952µs | +1.8% ParseWGSL/"particles.wgsl" | -104.83µs | -4.2% GenerateMSL/"particles.wgsl" | -1.079243ms | -9.4% GenerateSPIRV/"particles.wgsl" | -1.012483ms | -9.4% GenerateGLSL/"particles.wgsl" | -3.522106ms | -9.5% GenerateHLSL/"particles.wgsl" | -1.849666ms | -10.6% Issue: tint:1383 Change-Id: Ib691328538c597c06a75dfba392c99d2afbd5442 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/76961 Reviewed-by: Antonio Maiorano <amaiorano@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Ben Clayton <bclayton@google.com>
2022-01-22 20:32:38 +00:00
for (const int* p : static_cast<const Allocator&>(allocator).Objects()) {
EXPECT_EQ(*p, i);
i++;
}
EXPECT_EQ(i, N);
}
}
} // namespace
} // namespace tint