2021-06-15 13:26:17 +00:00
|
|
|
// Copyright 2021 the V8 project authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
2021-09-07 18:34:13 +00:00
|
|
|
// Flags: --experimental-wasm-gc --no-liftoff
|
2021-06-15 13:26:17 +00:00
|
|
|
|
|
|
|
d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
|
|
|
|
|
|
|
|
// This is benchmark to investigate at which point it is more efficient to call
|
|
|
|
// a memcpy-based builtin for array.copy, rather than copying
|
|
|
|
// element-by-element.
|
|
|
|
// How to run:
|
|
|
|
// - Set {iterations} to a high number to get better measurements
|
|
|
|
// - Change the value of {length} to find point at which the builtin becomes
|
|
|
|
// faster.
|
|
|
|
// - Change {array_type} if you want to test different types.
|
2021-09-03 16:03:59 +00:00
|
|
|
// Right now, the limit is found to be around 10.
|
2021-06-15 13:26:17 +00:00
|
|
|
(function ArrayCopyBenchmark() {
|
|
|
|
|
2021-09-03 16:03:59 +00:00
|
|
|
let array_length = 10;
|
2021-06-15 13:26:17 +00:00
|
|
|
let iterations = 1;
|
|
|
|
|
|
|
|
var builder = new WasmModuleBuilder();
|
|
|
|
let struct_index = builder.addStruct([makeField(kWasmI32, true),
|
|
|
|
makeField(kWasmI8, false)]);
|
|
|
|
let array_type = kWasmI32; // Also try kWasmI64, wasmOptRefType(struct_index)
|
|
|
|
var array_index = builder.addArray(array_type, true);
|
|
|
|
var from = builder.addGlobal(wasmOptRefType(array_index), true);
|
|
|
|
var to = builder.addGlobal(wasmOptRefType(array_index), true);
|
|
|
|
|
|
|
|
builder.addFunction("init", kSig_v_v)
|
|
|
|
.addBody([
|
|
|
|
...wasmI32Const(array_length),
|
|
|
|
kGCPrefix, kExprRttCanon, array_index,
|
2021-09-15 12:59:42 +00:00
|
|
|
kGCPrefix, kExprArrayNewDefaultWithRtt, array_index,
|
2021-06-15 13:26:17 +00:00
|
|
|
kExprGlobalSet, from.index,
|
|
|
|
...wasmI32Const(array_length),
|
|
|
|
kGCPrefix, kExprRttCanon, array_index,
|
2021-09-15 12:59:42 +00:00
|
|
|
kGCPrefix, kExprArrayNewDefaultWithRtt, array_index,
|
2021-06-15 13:26:17 +00:00
|
|
|
kExprGlobalSet, to.index
|
|
|
|
])
|
|
|
|
.exportFunc();
|
|
|
|
|
|
|
|
builder.addFunction("array_copy", kSig_v_v)
|
|
|
|
.addLocals(kWasmI32, 1)
|
|
|
|
.addBody([
|
|
|
|
kExprLoop, kWasmVoid,
|
|
|
|
kExprGlobalGet, to.index,
|
|
|
|
...wasmI32Const(0),
|
|
|
|
kExprGlobalGet, from.index,
|
|
|
|
...wasmI32Const(0),
|
|
|
|
...wasmI32Const(array_length),
|
|
|
|
kGCPrefix, kExprArrayCopy, array_index, array_index,
|
|
|
|
// Outer loop: run everything {iterations} times.
|
|
|
|
kExprLocalGet, 0, kExprI32Const, 1, kExprI32Add, kExprLocalSet, 0,
|
|
|
|
kExprLocalGet, 0, ...wasmI32Const(iterations), kExprI32LtS,
|
|
|
|
kExprBrIf, 0,
|
|
|
|
kExprEnd])
|
|
|
|
.exportFunc();
|
|
|
|
|
|
|
|
builder.addFunction("loop_copy", kSig_v_v)
|
|
|
|
.addLocals(kWasmI32, 2)
|
|
|
|
.addBody([
|
|
|
|
kExprLoop, kWasmVoid,
|
|
|
|
...wasmI32Const(0),
|
|
|
|
kExprLocalSet, 0,
|
|
|
|
kExprGlobalGet, from.index, kExprRefAsNonNull,
|
|
|
|
kExprGlobalGet, to.index, kExprRefAsNonNull,
|
|
|
|
kExprLet, kWasmVoid, 1, 2, kWasmRef, array_index,
|
|
|
|
kExprLoop, kWasmVoid,
|
|
|
|
kExprLocalGet, 1, // array
|
|
|
|
kExprLocalGet, 2, // index
|
|
|
|
// value
|
|
|
|
kExprLocalGet, 0, kExprLocalGet, 2,
|
|
|
|
kGCPrefix, kExprArrayGet, array_index,
|
|
|
|
// array.set
|
|
|
|
kGCPrefix, kExprArraySet, array_index,
|
|
|
|
// index++
|
|
|
|
kExprLocalGet, 2, kExprI32Const, 1, kExprI32Add, kExprLocalSet, 2,
|
|
|
|
// if (index < array_length) goto loop;
|
|
|
|
kExprLocalGet, 2, ...wasmI32Const(array_length), kExprI32LtU,
|
|
|
|
kExprBrIf, 0,
|
|
|
|
kExprEnd,
|
|
|
|
kExprEnd,
|
|
|
|
// Outer loop: run everything {iterations} times.
|
|
|
|
kExprLocalGet, 1, kExprI32Const, 1, kExprI32Add, kExprLocalSet, 1,
|
|
|
|
kExprLocalGet, 1, ...wasmI32Const(iterations), kExprI32LtS,
|
|
|
|
kExprBrIf, 0,
|
|
|
|
kExprEnd])
|
|
|
|
.exportFunc();
|
|
|
|
|
|
|
|
var instance = builder.instantiate({});
|
|
|
|
|
|
|
|
instance.exports.init();
|
|
|
|
print("Array length: " + array_length + ", #iterations: " + iterations);
|
|
|
|
{
|
|
|
|
let before = Date.now();
|
|
|
|
instance.exports.array_copy();
|
|
|
|
let after = Date.now();
|
|
|
|
print("array.copy: " + (after - before) + "ms");
|
|
|
|
}
|
|
|
|
{
|
|
|
|
let before = Date.now();
|
|
|
|
instance.exports.loop_copy();
|
|
|
|
let after = Date.now();
|
|
|
|
print("loop copy: " + (after - before) + "ms");
|
|
|
|
}
|
|
|
|
})();
|