Files
sdk/benchmarks/FfiStruct/dart/FfiStruct.dart
T
Daco Harkes fbf13f561f [benchmarks/ffi] Add micro and macro benchmarks for dart:ffi
Adds micro benchmarks to measure low level (1) C memory reads and writes from Dart and (2) calls from Dart into C. This CL also adds a macro benchmark to measure overall performance using BoringSSL to digest data. The shared libraries are precompiled for Linux and live in cipd packages. The benchmarks run on all hardware architectures (with the exception of Linux'es hardfp on Arm32: https://github.com/dart-lang/sdk/issues/36309).

Issue: https://github.com/dart-lang/sdk/issues/36247

Change-Id: I8dfb30cc66a26a2942bb09194c5eb0da0b6ca1b5
Cq-Include-Trybots: luci.dart.try:benchmark-linux-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/108724
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Jonas Termansen <sortie@google.com>
Auto-Submit: Daco Harkes <dacoharkes@google.com>
2019-07-19 14:59:57 +00:00

121 lines
2.2 KiB
Dart

// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Micro-benchmark for ffi struct field stores and loads.
//
// Only tests a single field because the FfiMemory benchmark already tests loads
// and stores of different field sizes.
import 'dart:ffi';
import 'package:benchmark_harness/benchmark_harness.dart';
//
// Struct field store (plus Pointer elementAt and load).
//
void doStoreInt32(Pointer<VeryLargeStruct> pointer, int length) {
for (int i = 0; i < length; i++) {
pointer.elementAt(i).load<VeryLargeStruct>().c = 1;
}
}
//
// Struct field load (plus Pointer elementAt and load).
//
int doLoadInt32(Pointer<VeryLargeStruct> pointer, int length) {
int x = 0;
for (int i = 0; i < length; i++) {
x += pointer.elementAt(i).load<VeryLargeStruct>().c;
}
return x;
}
//
// Benchmark fixture.
//
// Number of repeats: 1000
// * CPU: Intel(R) Xeon(R) Gold 6154
// * Architecture: x64
// * 150000 - 465000 us (without optimizations)
// * 14 - ??? us (expected with optimizations, on par with typed data)
const N = 1000;
class FieldLoadStore extends BenchmarkBase {
Pointer<VeryLargeStruct> pointer;
FieldLoadStore() : super("FfiStruct.FieldLoadStore");
void setup() => pointer = Pointer.allocate(count: N);
void teardown() => pointer.free();
void run() {
doStoreInt32(pointer, N);
final int x = doLoadInt32(pointer, N);
if (x != N) {
throw Exception("$name: Unexpected result: $x");
}
}
}
//
// Main driver.
//
main() {
final benchmarks = [
() => FieldLoadStore(),
];
benchmarks.forEach((benchmark) => benchmark().report());
}
//
// Test struct.
//
class VeryLargeStruct extends Struct<VeryLargeStruct> {
@Int8()
int a;
@Int16()
int b;
@Int32()
int c;
@Int64()
int d;
@Uint8()
int e;
@Uint16()
int f;
@Uint32()
int g;
@Uint64()
int h;
@IntPtr()
int i;
@Double()
double j;
@Float()
double k;
Pointer<VeryLargeStruct> parent;
@IntPtr()
int numChildren;
Pointer<VeryLargeStruct> children;
@Int8()
int smallLastField;
}