add ppc32be, and other fixes
This commit is contained in:
@@ -34,6 +34,8 @@ jobs:
|
|||||||
os: ubuntu-24.04
|
os: ubuntu-24.04
|
||||||
- target: linux-arm64
|
- target: linux-arm64
|
||||||
os: ubuntu-24.04
|
os: ubuntu-24.04
|
||||||
|
- target: linux-ppc32be
|
||||||
|
os: ubuntu-24.04
|
||||||
- target: macos-amd64
|
- target: macos-amd64
|
||||||
os: macos-14
|
os: macos-14
|
||||||
- target: macos-arm64
|
- target: macos-arm64
|
||||||
@@ -49,6 +51,12 @@ jobs:
|
|||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install --yes gcc-aarch64-linux-gnu
|
sudo apt-get install --yes gcc-aarch64-linux-gnu
|
||||||
|
|
||||||
|
- name: Install the Linux PPC32 big-endian cross-compiler
|
||||||
|
if: matrix.target == 'linux-ppc32be'
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install --yes gcc-powerpc-linux-gnu
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: make ${{ matrix.target }}
|
run: make ${{ matrix.target }}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
# The assembly kernels are architecture-specific:
|
# The assembly kernels are architecture-specific:
|
||||||
# src/fossmark.S AArch64 (ARM64)
|
# src/fossmark.S AArch64 (ARM64)
|
||||||
# src/fossmark_x86_64.S x86-64 (AMD64)
|
# src/fossmark_x86_64.S x86-64 (AMD64)
|
||||||
|
# src/fossmark_ppc32.c PowerPC 32-bit, including big-endian systems
|
||||||
# The C driver (src/main.c) is portable across architectures and OSes. A
|
# The C driver (src/main.c) is portable across architectures and OSes. A
|
||||||
# "binary that runs everywhere" is not possible - each OS/arch pair uses a
|
# "binary that runs everywhere" is not possible - each OS/arch pair uses a
|
||||||
# different executable format and instruction set - so output is named per
|
# different executable format and instruction set - so output is named per
|
||||||
@@ -42,6 +43,7 @@ DIST := dist
|
|||||||
DRIVER := src/main.c
|
DRIVER := src/main.c
|
||||||
ASM_ARM64 := src/fossmark.S
|
ASM_ARM64 := src/fossmark.S
|
||||||
ASM_AMD64 := src/fossmark_x86_64.S
|
ASM_AMD64 := src/fossmark_x86_64.S
|
||||||
|
SRC_PPC32 := src/fossmark_ppc32.c
|
||||||
|
|
||||||
# ---- host detection: normalise `uname -m` to our arch names ----
|
# ---- host detection: normalise `uname -m` to our arch names ----
|
||||||
HOST_ARCH := $(shell uname -m)
|
HOST_ARCH := $(shell uname -m)
|
||||||
@@ -50,10 +52,16 @@ ifneq (,$(filter aarch64 arm64,$(HOST_ARCH)))
|
|||||||
HOST_ASM := $(ASM_ARM64)
|
HOST_ASM := $(ASM_ARM64)
|
||||||
else ifneq (,$(filter x86_64 amd64,$(HOST_ARCH)))
|
else ifneq (,$(filter x86_64 amd64,$(HOST_ARCH)))
|
||||||
HOST_ARCHNAME := amd64
|
HOST_ARCHNAME := amd64
|
||||||
HOST_ASM := $(ASM_AMD64)
|
HOST_KERNEL := $(ASM_AMD64)
|
||||||
|
else ifneq (,$(filter ppc powerpc ppc32 powerpc32,$(HOST_ARCH)))
|
||||||
|
HOST_ARCHNAME := ppc32be
|
||||||
|
HOST_KERNEL := $(SRC_PPC32)
|
||||||
else
|
else
|
||||||
HOST_ARCHNAME := $(HOST_ARCH)
|
HOST_ARCHNAME := $(HOST_ARCH)
|
||||||
HOST_ASM := $(ASM_ARM64)
|
$(error unsupported host architecture '$(HOST_ARCH)')
|
||||||
|
endif
|
||||||
|
ifeq ($(HOST_ARCHNAME),arm64)
|
||||||
|
HOST_KERNEL := $(ASM_ARM64)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# ---- host OS name for the native binary ----
|
# ---- host OS name for the native binary ----
|
||||||
@@ -81,21 +89,27 @@ else
|
|||||||
endif
|
endif
|
||||||
CC_MACOS_ARM64 ?= $(CC)
|
CC_MACOS_ARM64 ?= $(CC)
|
||||||
CC_MACOS_AMD64 ?= $(CC)
|
CC_MACOS_AMD64 ?= $(CC)
|
||||||
|
ifeq ($(HOST_ARCHNAME),ppc32be)
|
||||||
|
CC_PPC32BE ?= $(CC)
|
||||||
|
else
|
||||||
|
CC_PPC32BE ?= powerpc-linux-gnu-gcc
|
||||||
|
endif
|
||||||
|
|
||||||
NATIVE_BIN := $(DIST)/fossmark-$(OSNAME)-$(HOST_ARCHNAME)
|
NATIVE_BIN := $(DIST)/fossmark-$(OSNAME)-$(HOST_ARCHNAME)
|
||||||
|
|
||||||
# `make` with no target builds the host binary, as before.
|
# `make` with no target builds the host binary, as before.
|
||||||
.DEFAULT_GOAL := native
|
.DEFAULT_GOAL := native
|
||||||
.PHONY: all native linux-arm64 linux-amd64 macos-arm64 macos-amd64 bench test clean
|
.PHONY: all native linux-arm64 linux-amd64 linux-ppc32be macos-arm64 macos-amd64 bench test clean
|
||||||
|
|
||||||
# `make all` builds both Linux binaries.
|
# `make all` builds all Linux binaries.
|
||||||
all: linux-arm64 linux-amd64
|
all: linux-arm64 linux-amd64 linux-ppc32be
|
||||||
|
|
||||||
# `make native` (and bare `make`) build for whatever host you are on.
|
# `make native` (and bare `make`) build for whatever host you are on.
|
||||||
native: $(NATIVE_BIN)
|
native: $(NATIVE_BIN)
|
||||||
|
|
||||||
linux-arm64: $(DIST)/fossmark-linux-arm64
|
linux-arm64: $(DIST)/fossmark-linux-arm64
|
||||||
linux-amd64: $(DIST)/fossmark-linux-amd64
|
linux-amd64: $(DIST)/fossmark-linux-amd64
|
||||||
|
linux-ppc32be: $(DIST)/fossmark-linux-ppc32be
|
||||||
macos-arm64: $(DIST)/fossmark-macos-arm64
|
macos-arm64: $(DIST)/fossmark-macos-arm64
|
||||||
macos-amd64: $(DIST)/fossmark-macos-amd64
|
macos-amd64: $(DIST)/fossmark-macos-amd64
|
||||||
|
|
||||||
@@ -107,6 +121,10 @@ $(DIST)/fossmark-linux-amd64: $(DRIVER) $(ASM_AMD64) | $(DIST)
|
|||||||
$(CC_AMD64) $(CFLAGS) $(PTHREAD) -o $@ $(DRIVER) $(ASM_AMD64) $(LDLIBS)
|
$(CC_AMD64) $(CFLAGS) $(PTHREAD) -o $@ $(DRIVER) $(ASM_AMD64) $(LDLIBS)
|
||||||
@echo "built $@"
|
@echo "built $@"
|
||||||
|
|
||||||
|
$(DIST)/fossmark-linux-ppc32be: $(DRIVER) $(SRC_PPC32) | $(DIST)
|
||||||
|
$(CC_PPC32BE) $(CFLAGS) $(PTHREAD) -o $@ $(DRIVER) $(SRC_PPC32) $(LDLIBS)
|
||||||
|
@echo "built $@"
|
||||||
|
|
||||||
$(DIST)/fossmark-macos-arm64: $(DRIVER) $(ASM_ARM64) | $(DIST)
|
$(DIST)/fossmark-macos-arm64: $(DRIVER) $(ASM_ARM64) | $(DIST)
|
||||||
$(CC_MACOS_ARM64) -arch arm64 $(CFLAGS) $(PTHREAD) -o $@ $(DRIVER) $(ASM_ARM64) $(LDLIBS)
|
$(CC_MACOS_ARM64) -arch arm64 $(CFLAGS) $(PTHREAD) -o $@ $(DRIVER) $(ASM_ARM64) $(LDLIBS)
|
||||||
@echo "built $@"
|
@echo "built $@"
|
||||||
@@ -124,6 +142,9 @@ endif
|
|||||||
ifeq ($(OSNAME)-$(HOST_ARCHNAME),linux-amd64)
|
ifeq ($(OSNAME)-$(HOST_ARCHNAME),linux-amd64)
|
||||||
NATIVE_HAS_RULE := yes
|
NATIVE_HAS_RULE := yes
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(OSNAME)-$(HOST_ARCHNAME),linux-ppc32be)
|
||||||
|
NATIVE_HAS_RULE := yes
|
||||||
|
endif
|
||||||
ifeq ($(OSNAME)-$(HOST_ARCHNAME),macos-arm64)
|
ifeq ($(OSNAME)-$(HOST_ARCHNAME),macos-arm64)
|
||||||
NATIVE_HAS_RULE := yes
|
NATIVE_HAS_RULE := yes
|
||||||
endif
|
endif
|
||||||
@@ -131,8 +152,8 @@ ifeq ($(OSNAME)-$(HOST_ARCHNAME),macos-amd64)
|
|||||||
NATIVE_HAS_RULE := yes
|
NATIVE_HAS_RULE := yes
|
||||||
endif
|
endif
|
||||||
ifneq ($(NATIVE_HAS_RULE),yes)
|
ifneq ($(NATIVE_HAS_RULE),yes)
|
||||||
$(NATIVE_BIN): $(DRIVER) $(HOST_ASM) | $(DIST)
|
$(NATIVE_BIN): $(DRIVER) $(HOST_KERNEL) | $(DIST)
|
||||||
$(CC) $(CFLAGS) $(PTHREAD) -o $@ $(DRIVER) $(HOST_ASM) $(LDLIBS)
|
$(CC) $(CFLAGS) $(PTHREAD) -o $@ $(DRIVER) $(HOST_KERNEL) $(LDLIBS)
|
||||||
@echo "built $@"
|
@echo "built $@"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -145,7 +166,7 @@ bench: $(NATIVE_BIN)
|
|||||||
|
|
||||||
# Build and run the kernel correctness tests for the host arch.
|
# Build and run the kernel correctness tests for the host arch.
|
||||||
test: | $(DIST)
|
test: | $(DIST)
|
||||||
$(CC) $(CFLAGS) $(PTHREAD) -o $(DIST)/test_kernels src/test_kernels.c $(HOST_ASM) $(LDLIBS)
|
$(CC) $(CFLAGS) $(PTHREAD) -o $(DIST)/test_kernels src/test_kernels.c $(HOST_KERNEL) $(LDLIBS)
|
||||||
./$(DIST)/test_kernels
|
./$(DIST)/test_kernels
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
|||||||
@@ -5,9 +5,10 @@ small C driver. It measures each workload twice: once on a single core and once
|
|||||||
across every available core. The final report includes separate single-core and
|
across every available core. The final report includes separate single-core and
|
||||||
multicore scores.
|
multicore scores.
|
||||||
|
|
||||||
The repository currently builds an executable named `fossmark` for ARM64 and
|
The repository currently builds an executable named `fossmark` for ARM64,
|
||||||
x86-64. The C driver handles timing, memory, threads, output, and scoring. The
|
x86-64, and 32-bit big-endian PowerPC. The C driver handles timing, memory,
|
||||||
performance-sensitive kernels live in architecture-specific assembly files.
|
threads, output, and scoring. Performance-sensitive kernels live in
|
||||||
|
architecture-specific backend files.
|
||||||
|
|
||||||
## Workloads
|
## Workloads
|
||||||
|
|
||||||
@@ -48,6 +49,7 @@ Other targets are available for explicit platforms and architectures:
|
|||||||
```sh
|
```sh
|
||||||
make linux-arm64
|
make linux-arm64
|
||||||
make linux-amd64
|
make linux-amd64
|
||||||
|
make linux-ppc32be
|
||||||
make macos-arm64
|
make macos-arm64
|
||||||
make macos-amd64
|
make macos-amd64
|
||||||
make all
|
make all
|
||||||
@@ -59,6 +61,7 @@ toolchain. Override the target compiler when its name differs from the default:
|
|||||||
```sh
|
```sh
|
||||||
make linux-arm64 CC_ARM64=aarch64-linux-gnu-gcc
|
make linux-arm64 CC_ARM64=aarch64-linux-gnu-gcc
|
||||||
make linux-amd64 CC_AMD64=x86_64-linux-gnu-gcc
|
make linux-amd64 CC_AMD64=x86_64-linux-gnu-gcc
|
||||||
|
make linux-ppc32be CC_PPC32BE=powerpc-linux-gnu-gcc
|
||||||
```
|
```
|
||||||
|
|
||||||
Apple Clang can build either macOS architecture with `-arch`. Windows timing
|
Apple Clang can build either macOS architecture with `-arch`. Windows timing
|
||||||
@@ -77,7 +80,8 @@ The exact filename depends on the host platform and architecture.
|
|||||||
|
|
||||||
Pushing a Git tag runs the GitHub Actions build and correctness tests. If they
|
Pushing a Git tag runs the GitHub Actions build and correctness tests. If they
|
||||||
succeed, the workflow creates a GitHub Release named `Release <tag name>` with
|
succeed, the workflow creates a GitHub Release named `Release <tag name>` with
|
||||||
Linux and macOS archives for AMD64 and ARM64, plus a `SHA256SUMS` file.
|
Linux archives for AMD64, ARM64, and PPC32 big-endian, macOS archives for AMD64
|
||||||
|
and ARM64, and a `SHA256SUMS` file.
|
||||||
|
|
||||||
## Scores
|
## Scores
|
||||||
|
|
||||||
@@ -115,13 +119,14 @@ normal.
|
|||||||
|
|
||||||
## Architecture support
|
## Architecture support
|
||||||
|
|
||||||
The assembly kernels use only baseline instructions for their architecture:
|
The kernel backends use only baseline instructions for their architecture:
|
||||||
|
|
||||||
* `src/fossmark.S` uses ARMv8-A and NEON under AAPCS64.
|
* `src/fossmark.S` uses ARMv8-A and NEON under AAPCS64.
|
||||||
* `src/fossmark_x86_64.S` uses baseline x86-64 and SSE2 under the System V ABI.
|
* `src/fossmark_x86_64.S` uses baseline x86-64 and SSE2 under the System V ABI.
|
||||||
|
* `src/fossmark_ppc32.c` is endian-safe and uses baseline 32-bit PowerPC operations. It avoids AltiVec so it runs on the Wii's PowerPC 750CL-class CPU.
|
||||||
|
|
||||||
The kernel files contain no system calls or calls into the C library. The same
|
The assembly kernel files contain no system calls or calls into the C library.
|
||||||
ARM64 source can be assembled for Linux, macOS, Windows, and BSD object formats.
|
The same ARM64 source can be assembled for Linux, macOS, Windows, and BSD object formats.
|
||||||
The current x86-64 source supports Linux, macOS, and the BSDs that use the
|
The current x86-64 source supports Linux, macOS, and the BSDs that use the
|
||||||
System V calling convention.
|
System V calling convention.
|
||||||
|
|
||||||
@@ -149,8 +154,8 @@ with a nonzero status if any check fails.
|
|||||||
src/main.c portable benchmark driver and scoring
|
src/main.c portable benchmark driver and scoring
|
||||||
src/fossmark.S ARM64 kernels
|
src/fossmark.S ARM64 kernels
|
||||||
src/fossmark_x86_64.S x86-64 kernels
|
src/fossmark_x86_64.S x86-64 kernels
|
||||||
|
src/fossmark_ppc32.c PPC32 big-endian kernels
|
||||||
src/test_kernels.c correctness suite
|
src/test_kernels.c correctness suite
|
||||||
Makefile native and cross-build targets
|
Makefile native and cross-build targets
|
||||||
dist/ generated binaries
|
dist/ generated binaries
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
Vendored
BIN
Binary file not shown.
@@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
* Portable kernel backend for 32-bit PowerPC.
|
||||||
|
*
|
||||||
|
* Keeping this backend in C lets the compiler implement 64-bit arguments and
|
||||||
|
* returns according to the platform's PPC32 ABI. All byte-oriented formats
|
||||||
|
* are decoded explicitly, so the code is correct on big-endian systems.
|
||||||
|
*/
|
||||||
|
#include <math.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static uint32_t rotl32(uint32_t x, unsigned n)
|
||||||
|
{
|
||||||
|
return (x << n) | (x >> (32 - n));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t fm_int_math(uint64_t iters)
|
||||||
|
{
|
||||||
|
uint64_t a = 0x9e3779b97f4a7c15ULL, b = 0xbf58476d1ce4e5b9ULL;
|
||||||
|
uint64_t c = 0x94d049bb133111ebULL, d = 0x2545f4914f6cdd1dULL;
|
||||||
|
uint64_t i;
|
||||||
|
if (!iters) return 0;
|
||||||
|
for (i = 0; i < iters; i++) {
|
||||||
|
a = a * 0xdeadbeefU + b; b = b * 0xdeadbeefU + c;
|
||||||
|
c = c * 0xdeadbeefU + d; d = d * 0xdeadbeefU + a;
|
||||||
|
a ^= c >> 29; b ^= d << 17; c ^= (a >> 31) | (a << 33);
|
||||||
|
d ^= b >> 7; a += c / 0xdeadbeefU; b += d / 0xdeadbeefU;
|
||||||
|
}
|
||||||
|
return a ^ b ^ c ^ d;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t fm_fp_math(uint64_t iters)
|
||||||
|
{
|
||||||
|
double a = 1.5, b = 2.5, c = 3.5, d = .5, out;
|
||||||
|
uint64_t bits, i;
|
||||||
|
if (!iters) return 0;
|
||||||
|
for (i = 0; i < iters; i++) {
|
||||||
|
a = fmin(a * 1.0625 + .0009765625, 2.0);
|
||||||
|
b = fmin(b * 1.0625 + .0009765625, 2.0);
|
||||||
|
c = fmin(c * 1.0625 + .0009765625, 2.0) + sqrt(a);
|
||||||
|
d = fmax(fabs(fmin(d * 1.0625 + .0009765625, 2.0) + sqrt(b)), 1.0);
|
||||||
|
a += 1.0 / (c + 1.0); b += 1.0 / (d + 1.0);
|
||||||
|
}
|
||||||
|
out = a + b + c + d;
|
||||||
|
memcpy(&bits, &out, sizeof bits);
|
||||||
|
return bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t fm_primes(uint64_t limit, uint8_t *sieve)
|
||||||
|
{
|
||||||
|
uint64_t i, j, count = 0;
|
||||||
|
if (limit < 2) return 0;
|
||||||
|
memset(sieve, 0, (size_t)limit);
|
||||||
|
sieve[0] = sieve[1] = 1;
|
||||||
|
for (i = 2; i <= (limit - 1) / i; i++)
|
||||||
|
if (!sieve[i]) for (j = i * i; j < limit; j += i) sieve[j] = 1;
|
||||||
|
for (i = 2; i < limit; i++) count += !sieve[i];
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t fm_simd(uint64_t iters, void *memory)
|
||||||
|
{
|
||||||
|
uint32_t *v = (uint32_t *)memory;
|
||||||
|
uint32_t a[8]; uint64_t i; unsigned j; uint32_t sum = 0;
|
||||||
|
if (!iters) return 0;
|
||||||
|
memcpy(a, v, sizeof a);
|
||||||
|
for (i = 0; i < iters; i++)
|
||||||
|
for (j = 0; j < 8; j++) a[j] = rotl32(a[j] + a[(j + 1) & 7] * (j + 3), (j + 5) & 31);
|
||||||
|
for (j = 0; j < 8; j++) sum ^= a[j];
|
||||||
|
memcpy(v, a, sizeof a);
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t load32_native(const uint8_t *p)
|
||||||
|
{
|
||||||
|
uint32_t v; memcpy(&v, p, sizeof v); return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t fm_compress(const uint8_t *src, uint64_t len, uint32_t *ht)
|
||||||
|
{
|
||||||
|
uint64_t ip = 0, anchor = 0, out = 0, ref, ml, lit;
|
||||||
|
memset(ht, 0, (size_t)(1U << 16) * sizeof *ht);
|
||||||
|
if (len < 16) return len + 1;
|
||||||
|
while (ip < len - 12) {
|
||||||
|
uint32_t seq = load32_native(src + ip);
|
||||||
|
uint32_t h = (uint32_t)(seq * 2654435761U) >> 16;
|
||||||
|
ref = ht[h]; ht[h] = (uint32_t)ip;
|
||||||
|
if (ref >= ip || ip - ref >= 65536 || load32_native(src + ref) != seq) { ip++; continue; }
|
||||||
|
for (ml = 4; ip + ml < len && src[ip + ml] == src[ref + ml]; ml++) {}
|
||||||
|
lit = ip - anchor; out += lit + 3 + (lit >= 15) + (ml >= 19);
|
||||||
|
ip += ml; anchor = ip;
|
||||||
|
}
|
||||||
|
return out + (len - anchor) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t load32le(const uint8_t *p)
|
||||||
|
{
|
||||||
|
return (uint32_t)p[0] | (uint32_t)p[1] << 8 | (uint32_t)p[2] << 16 | (uint32_t)p[3] << 24;
|
||||||
|
}
|
||||||
|
static void store32le(uint8_t *p, uint32_t v)
|
||||||
|
{
|
||||||
|
p[0] = (uint8_t)v; p[1] = (uint8_t)(v >> 8); p[2] = (uint8_t)(v >> 16); p[3] = (uint8_t)(v >> 24);
|
||||||
|
}
|
||||||
|
#define QR(a,b,c,d) do { a+=b; d=rotl32(d^a,16); c+=d; b=rotl32(b^c,12); a+=b; d=rotl32(d^a,8); c+=d; b=rotl32(b^c,7); } while (0)
|
||||||
|
uint64_t fm_chacha20(uint8_t *buf, uint64_t len, const uint8_t key[32], uint64_t passes)
|
||||||
|
{
|
||||||
|
static const uint32_t sigma[4] = {0x61707865,0x3320646e,0x79622d32,0x6b206574};
|
||||||
|
uint32_t base[16], x[16], counter = 0, checksum = 0; uint64_t pass, off; int i, r;
|
||||||
|
len &= ~(uint64_t)63; if (!len || !passes) return 0;
|
||||||
|
memcpy(base, sigma, 16); for (i=0;i<8;i++) base[4+i]=load32le(key+4*i);
|
||||||
|
base[13]=base[14]=base[15]=0;
|
||||||
|
for (pass=0;pass<passes;pass++) for (off=0;off<len;off+=64) {
|
||||||
|
base[12]=counter++; memcpy(x,base,sizeof x);
|
||||||
|
for(r=0;r<10;r++) { QR(x[0],x[4],x[8],x[12]); QR(x[1],x[5],x[9],x[13]); QR(x[2],x[6],x[10],x[14]); QR(x[3],x[7],x[11],x[15]); QR(x[0],x[5],x[10],x[15]); QR(x[1],x[6],x[11],x[12]); QR(x[2],x[7],x[8],x[13]); QR(x[3],x[4],x[9],x[14]); }
|
||||||
|
for(i=0;i<16;i++) { uint32_t k=x[i]+base[i]; uint8_t t[4]; store32le(t,k); buf[off+4*i]^=t[0]; buf[off+4*i+1]^=t[1]; buf[off+4*i+2]^=t[2]; buf[off+4*i+3]^=t[3]; checksum^=k; }
|
||||||
|
}
|
||||||
|
return checksum;
|
||||||
|
}
|
||||||
|
#undef QR
|
||||||
|
|
||||||
|
uint64_t fm_physics(double *b, uint64_t n, uint64_t steps)
|
||||||
|
{
|
||||||
|
uint64_t s,i,j,bits; double sum=0;
|
||||||
|
if (!n || !steps) return 0;
|
||||||
|
for(s=0;s<steps;s++) { for(i=0;i<n;i++) { double ax=0,ay=0,az=0; for(j=0;j<n;j++) { double dx=b[8*j]-b[8*i],dy=b[8*j+1]-b[8*i+1],dz=b[8*j+2]-b[8*i+2]; double q=1.0/sqrt(dx*dx+dy*dy+dz*dz+.0625); q=q*q*q*b[8*j+3]; ax+=dx*q; ay+=dy*q; az+=dz*q; } b[8*i+4]+=ax*.0078125; b[8*i+5]+=ay*.0078125; b[8*i+6]+=az*.0078125; } for(i=0;i<n;i++) { b[8*i]+=b[8*i+4]*.0078125; b[8*i+1]+=b[8*i+5]*.0078125; b[8*i+2]+=b[8*i+6]*.0078125; } }
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
sum += b[8*i+4] + b[8*i+5] + b[8*i+6];
|
||||||
|
memcpy(&bits, &sum, sizeof bits);
|
||||||
|
return bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sift(uint32_t *a, uint64_t root, uint64_t end) { for (;;) { uint64_t c=root*2+1; uint32_t t; if(c>=end)return; if(c+1<end&&a[c+1]>a[c])c++; if(a[root]>=a[c])return; t=a[root];a[root]=a[c];a[c]=t;root=c; } }
|
||||||
|
uint64_t fm_sort(uint32_t *a, uint64_t n)
|
||||||
|
{
|
||||||
|
uint64_t i,end,sum=0; uint32_t t; if(n<2)return n?a[0]:0;
|
||||||
|
for (i = n / 2; i; i--)
|
||||||
|
sift(a, i - 1, n);
|
||||||
|
for (end = n - 1; end; end--) {
|
||||||
|
t = a[0]; a[0] = a[end]; a[end] = t;
|
||||||
|
sift(a, 0, end);
|
||||||
|
}
|
||||||
|
for(i=0;i<n;i++){sum=(sum>>7)|(sum<<57);sum^=a[i];sum+=a[i];} return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t fm_chase(void **ptrs, uint64_t steps)
|
||||||
|
{
|
||||||
|
void **p=ptrs; uint64_t i; if(!steps)return 0; for(i=0;i<steps;i++)p=(void **)*p; return (uint64_t)((uintptr_t)p-(uintptr_t)ptrs);
|
||||||
|
}
|
||||||
+7
-6
@@ -45,6 +45,11 @@
|
|||||||
# define D_INT "64-bit ALU: imul, mul, div, bitops"
|
# define D_INT "64-bit ALU: imul, mul, div, bitops"
|
||||||
# define D_FP "double: mulsd/addsd, divsd, sqrtsd"
|
# define D_FP "double: mulsd/addsd, divsd, sqrtsd"
|
||||||
# define D_SIMD "SSE2: 128-bit integer + float"
|
# define D_SIMD "SSE2: 128-bit integer + float"
|
||||||
|
#elif defined(__powerpc__) && !defined(__powerpc64__)
|
||||||
|
# define FM_ARCH "PowerPC 32-bit big-endian"
|
||||||
|
# define D_INT "PPC32 integer ALU and software 64-bit arithmetic"
|
||||||
|
# define D_FP "PowerPC scalar double-precision floating point"
|
||||||
|
# define D_SIMD "PPC32 parallel integer workload"
|
||||||
#else
|
#else
|
||||||
# define FM_ARCH "unknown"
|
# define FM_ARCH "unknown"
|
||||||
# define D_INT "64-bit integer ALU"
|
# define D_INT "64-bit integer ALU"
|
||||||
@@ -603,14 +608,12 @@ static double display_metric(const struct test *t, const struct result *r)
|
|||||||
static void print_header(void)
|
static void print_header(void)
|
||||||
{
|
{
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf(" fossmark 1.0 - multi-core CPU benchmark\n");
|
printf(" fossbench1.0 - multi-core CPU benchmark\n");
|
||||||
printf(" ------------------------------------------------------------------\n");
|
printf(" ------------------------------------------------------------------\n");
|
||||||
printf(" platform: %s/%s\n", FM_OS, FM_ARCH);
|
printf(" platform: %s/%s\n", FM_OS, FM_ARCH);
|
||||||
printf(" cores: %ld (each test is run once on 1 core, once on all %ld)\n",
|
printf(" cores: %ld\n",
|
||||||
g_ncores, g_ncores);
|
g_ncores, g_ncores);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf(" RATE/TIME/SCORE below are the all-core (multi-core) pass.\n");
|
|
||||||
printf("\n");
|
|
||||||
printf(" %-24s %12s %-11s %8s %9s\n",
|
printf(" %-24s %12s %-11s %8s %9s\n",
|
||||||
"TEST", "RATE", "UNIT", "TIME", "SCORE");
|
"TEST", "RATE", "UNIT", "TIME", "SCORE");
|
||||||
printf(" --------------------------------------------------------------------------\n");
|
printf(" --------------------------------------------------------------------------\n");
|
||||||
@@ -700,8 +703,6 @@ int main(int argc, char **argv)
|
|||||||
exp(multi_log_sum / weight_sum));
|
exp(multi_log_sum / weight_sum));
|
||||||
printf(" %-24s %44.0f\n", "SINGLECORE SCORE",
|
printf(" %-24s %44.0f\n", "SINGLECORE SCORE",
|
||||||
exp(single_log_sum / weight_sum));
|
exp(single_log_sum / weight_sum));
|
||||||
printf(" %-24s (weighted geometric means, reference machine = %.0f)\n",
|
|
||||||
"", FM_TARGET_SCORE);
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
teardown();
|
teardown();
|
||||||
|
|||||||
Reference in New Issue
Block a user