From d3381c6a9c6e74edb41629b661226602e32c2235 Mon Sep 17 00:00:00 2001 From: Martijn Courteaux Date: Sat, 2 Mar 2024 11:50:27 +0100 Subject: [PATCH] Linux build script and some platform code fixes for Linux. Minor reporting changes to the repetition tester to make it more readable to me. --- perfaware/part2/build.sh | 23 ++++++++++++++++++ perfaware/part2/build_asm.sh | 19 +++++++++++++++ perfaware/part2/build_single.sh | 22 +++++++++++++++++ perfaware/part2/build_single_asm.sh | 24 +++++++++++++++++++ perfaware/part3/build.sh | 23 ++++++++++++++++++ perfaware/part3/build_asm.sh | 19 +++++++++++++++ perfaware/part3/build_single.sh | 22 +++++++++++++++++ perfaware/part3/build_single_asm.sh | 24 +++++++++++++++++++ .../part3/listing_0102_read_overhead_test.cpp | 7 +++++- .../part3/listing_0104_read_overhead_main.cpp | 2 ++ .../part3/listing_0108_platform_metrics.cpp | 1 + ...sting_0109_pagefault_repetition_tester.cpp | 11 +++++++-- perfaware/part3/listing_0126_os_platform.cpp | 3 +++ perfaware/part3/listing_0137_os_platform.cpp | 12 ++++++++-- 14 files changed, 207 insertions(+), 5 deletions(-) create mode 100755 perfaware/part2/build.sh create mode 100755 perfaware/part2/build_asm.sh create mode 100755 perfaware/part2/build_single.sh create mode 100755 perfaware/part2/build_single_asm.sh create mode 100755 perfaware/part3/build.sh create mode 100755 perfaware/part3/build_asm.sh create mode 100755 perfaware/part3/build_single.sh create mode 100755 perfaware/part3/build_single_asm.sh diff --git a/perfaware/part2/build.sh b/perfaware/part2/build.sh new file mode 100755 index 00000000..b5280000 --- /dev/null +++ b/perfaware/part2/build.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +if [ -z "${CXX}" ]; then + echo "WARNING: Environment variable CXX not set." + exit +fi +# Check if `${CXX}` is in the PATH +if ! command -v ${CXX} &> /dev/null; then + echo "WARNING: ${CXX} not found -- executables will not be built" + echo "Set CXX environment variable to a working C++ compiler." + exit +fi + +# Set buildpat based on the first script argument +if [ -z "$1" ]; then + for g in ./*_main.cpp ; do + ./build_single.sh "$g" + done +else + for g in ./*$1*_main.cpp ; do + ./build_single.sh "$g" + done +fi diff --git a/perfaware/part2/build_asm.sh b/perfaware/part2/build_asm.sh new file mode 100755 index 00000000..a8adb5a6 --- /dev/null +++ b/perfaware/part2/build_asm.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# Check if `nasm` is in the PATH +if ! command -v nasm &> /dev/null; then + echo "WARNING: nasm not found -- ASM libs will not be built" +fi + +# Set buildpat based on the first script argument +if [ -z "$1" ]; then + buildpat="*.asm" + for g in ./*asm ; do + ./build_single_asm.sh "$g" + done +else + for g in ./*$1*.asm ; do + ./build_single_asm.sh "$g" + done +fi + diff --git a/perfaware/part2/build_single.sh b/perfaware/part2/build_single.sh new file mode 100755 index 00000000..c5ae0b43 --- /dev/null +++ b/perfaware/part2/build_single.sh @@ -0,0 +1,22 @@ +#!/bin/bash -x + +# Create 'build' directory if it does not exist +if [ ! -d build ]; then + mkdir build +fi +pushd build + +# Check if `clang++` is in the PATH and compile with `clang++` if available +if command -v ${CXX} &> /dev/null; then + # Extract the filename without extension from the first argument + filename=$(basename -- "$1") + extension="${filename##*.}" + filename="${filename%.*}" + + # Compile with clang++ + ${CXX} -mavx2 -g -Wall -fuse-ld=lld ../"$1" -L . -o "${filename}_dc" + ${CXX} -mavx2 -O3 -g -Wall -fuse-ld=lld ../"$1" -L . -o "${filename}_rc" +fi + +popd + diff --git a/perfaware/part2/build_single_asm.sh b/perfaware/part2/build_single_asm.sh new file mode 100755 index 00000000..a01b2def --- /dev/null +++ b/perfaware/part2/build_single_asm.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +# Create 'build' directory if it does not exist +if [ ! -d build ]; then + mkdir build +fi +pushd build + +# Check if `nasm` is in the PATH and compile with `nasm` if available +if command -v nasm &> /dev/null; then + # Extract the filename without extension from the first argument + filename=$(basename -- "$1") + extension="${filename##*.}" + filename="${filename%.*}" + + # Compile with nasm + nasm -f elf64 -o "${filename}.o" ../"$1" + + # Create a static library from the object file, using 'ar' as a likely substitute for 'lib' + ar rcs "${filename}.a" "${filename}.o" +fi + +popd + diff --git a/perfaware/part3/build.sh b/perfaware/part3/build.sh new file mode 100755 index 00000000..b5280000 --- /dev/null +++ b/perfaware/part3/build.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +if [ -z "${CXX}" ]; then + echo "WARNING: Environment variable CXX not set." + exit +fi +# Check if `${CXX}` is in the PATH +if ! command -v ${CXX} &> /dev/null; then + echo "WARNING: ${CXX} not found -- executables will not be built" + echo "Set CXX environment variable to a working C++ compiler." + exit +fi + +# Set buildpat based on the first script argument +if [ -z "$1" ]; then + for g in ./*_main.cpp ; do + ./build_single.sh "$g" + done +else + for g in ./*$1*_main.cpp ; do + ./build_single.sh "$g" + done +fi diff --git a/perfaware/part3/build_asm.sh b/perfaware/part3/build_asm.sh new file mode 100755 index 00000000..a8adb5a6 --- /dev/null +++ b/perfaware/part3/build_asm.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# Check if `nasm` is in the PATH +if ! command -v nasm &> /dev/null; then + echo "WARNING: nasm not found -- ASM libs will not be built" +fi + +# Set buildpat based on the first script argument +if [ -z "$1" ]; then + buildpat="*.asm" + for g in ./*asm ; do + ./build_single_asm.sh "$g" + done +else + for g in ./*$1*.asm ; do + ./build_single_asm.sh "$g" + done +fi + diff --git a/perfaware/part3/build_single.sh b/perfaware/part3/build_single.sh new file mode 100755 index 00000000..c5ae0b43 --- /dev/null +++ b/perfaware/part3/build_single.sh @@ -0,0 +1,22 @@ +#!/bin/bash -x + +# Create 'build' directory if it does not exist +if [ ! -d build ]; then + mkdir build +fi +pushd build + +# Check if `clang++` is in the PATH and compile with `clang++` if available +if command -v ${CXX} &> /dev/null; then + # Extract the filename without extension from the first argument + filename=$(basename -- "$1") + extension="${filename##*.}" + filename="${filename%.*}" + + # Compile with clang++ + ${CXX} -mavx2 -g -Wall -fuse-ld=lld ../"$1" -L . -o "${filename}_dc" + ${CXX} -mavx2 -O3 -g -Wall -fuse-ld=lld ../"$1" -L . -o "${filename}_rc" +fi + +popd + diff --git a/perfaware/part3/build_single_asm.sh b/perfaware/part3/build_single_asm.sh new file mode 100755 index 00000000..a01b2def --- /dev/null +++ b/perfaware/part3/build_single_asm.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +# Create 'build' directory if it does not exist +if [ ! -d build ]; then + mkdir build +fi +pushd build + +# Check if `nasm` is in the PATH and compile with `nasm` if available +if command -v nasm &> /dev/null; then + # Extract the filename without extension from the first argument + filename=$(basename -- "$1") + extension="${filename##*.}" + filename="${filename%.*}" + + # Compile with nasm + nasm -f elf64 -o "${filename}.o" ../"$1" + + # Create a static library from the object file, using 'ar' as a likely substitute for 'lib' + ar rcs "${filename}.a" "${filename}.o" +fi + +popd + diff --git a/perfaware/part3/listing_0102_read_overhead_test.cpp b/perfaware/part3/listing_0102_read_overhead_test.cpp index 4747208f..3dc859df 100644 --- a/perfaware/part3/listing_0102_read_overhead_test.cpp +++ b/perfaware/part3/listing_0102_read_overhead_test.cpp @@ -14,9 +14,11 @@ LISTING 102 ======================================================================== */ +#if _WIN32 #include -#include #include +#endif +#include struct read_parameters { @@ -57,6 +59,8 @@ static void ReadViaFRead(repetition_tester *Tester, read_parameters *Params) } } +#if _WIN32 + static void ReadViaRead(repetition_tester *Tester, read_parameters *Params) { while(IsTesting(Tester)) @@ -149,3 +153,4 @@ static void ReadViaReadFile(repetition_tester *Tester, read_parameters *Params) } } } +#endif diff --git a/perfaware/part3/listing_0104_read_overhead_main.cpp b/perfaware/part3/listing_0104_read_overhead_main.cpp index 3cdd2df0..9004bb46 100644 --- a/perfaware/part3/listing_0104_read_overhead_main.cpp +++ b/perfaware/part3/listing_0104_read_overhead_main.cpp @@ -53,8 +53,10 @@ struct test_function test_function TestFunctions[] = { {"fread", ReadViaFRead}, +#if _WIN32 {"_read", ReadViaRead}, {"ReadFile", ReadViaReadFile}, +#endif }; int main(int ArgCount, char **Args) diff --git a/perfaware/part3/listing_0108_platform_metrics.cpp b/perfaware/part3/listing_0108_platform_metrics.cpp index 96499565..6c42fba3 100644 --- a/perfaware/part3/listing_0108_platform_metrics.cpp +++ b/perfaware/part3/listing_0108_platform_metrics.cpp @@ -64,6 +64,7 @@ static void InitializeOSMetrics(void) #include #include +#include static u64 GetOSTimerFreq(void) { diff --git a/perfaware/part3/listing_0109_pagefault_repetition_tester.cpp b/perfaware/part3/listing_0109_pagefault_repetition_tester.cpp index 2aa69c89..c3e88b27 100644 --- a/perfaware/part3/listing_0109_pagefault_repetition_tester.cpp +++ b/perfaware/part3/listing_0109_pagefault_repetition_tester.cpp @@ -87,13 +87,13 @@ static void PrintValue(char const *Label, repetition_value Value, u64 CPUTimerFr if(CPUTimerFreq) { f64 Seconds = SecondsFromCPUTime(E[RepValue_CPUTimer], CPUTimerFreq); - printf(" (%fms)", 1000.0f*Seconds); + printf(" (%8.3fms)", 1000.0f*Seconds); if(E[RepValue_ByteCount] > 0) { f64 Gigabyte = (1024.0f * 1024.0f * 1024.0f); f64 Bandwidth = E[RepValue_ByteCount] / (Gigabyte * Seconds); - printf(" %fgb/s", Bandwidth); + printf(" %9.4fgb/s", Bandwidth); } } @@ -146,6 +146,7 @@ static void NewTestWave(repetition_tester *Tester, u64 TargetProcessedByteCount, Tester->TryForTime = SecondsToTry*CPUTimerFreq; Tester->TestsStartedAt = ReadCPUTimer(); + //printf("\n"); // Move to the next line to start the live Min reporting. } static void BeginTime(repetition_tester *Tester) @@ -215,8 +216,14 @@ static b32 IsTesting(repetition_tester *Tester) if(Tester->PrintNewMinimums) { +#if !_WIN32 + printf("\033[2K\r"); +#endif PrintValue("Min", Results->Min, Tester->CPUTimerFreq); +#if _WIN32 printf(" \r"); +#endif + fflush(stdout); } } diff --git a/perfaware/part3/listing_0126_os_platform.cpp b/perfaware/part3/listing_0126_os_platform.cpp index 7b6a8de3..365a26b2 100644 --- a/perfaware/part3/listing_0126_os_platform.cpp +++ b/perfaware/part3/listing_0126_os_platform.cpp @@ -97,11 +97,13 @@ static void InitializeOSPlatform(void) #include #include +#include struct os_platform { b32 Initialized; u64 CPUTimerFreq; + u64 LargePageSize; // NOTE(casey): This will be 0 when large pages are not supported (which is most of the time!) }; static os_platform GlobalOSPlatform; @@ -143,6 +145,7 @@ static void InitializeOSPlatform(void) { GlobalOSPlatform.Initialized = true; GlobalOSPlatform.CPUTimerFreq = EstimateCPUTimerFreq(); + GlobalOSPlatform.LargePageSize = 2048 * 1024; } } diff --git a/perfaware/part3/listing_0137_os_platform.cpp b/perfaware/part3/listing_0137_os_platform.cpp index 3e39dcf4..dfc81dc3 100644 --- a/perfaware/part3/listing_0137_os_platform.cpp +++ b/perfaware/part3/listing_0137_os_platform.cpp @@ -114,11 +114,18 @@ static void InitializeOSPlatform(void) #include #include +#include +#include +#include +#include +#include +#include struct os_platform { b32 Initialized; u64 CPUTimerFreq; + u64 LargePageSize; // NOTE(casey): This will be 0 when large pages are not supported (which is most of the time!) }; static os_platform GlobalOSPlatform; @@ -167,7 +174,7 @@ static b32 ReadOSRandomBytes(u64 Count, void *Dest) // and do multiple read()'s to make sure you filled the entire buffer. int DevRandom = open("/dev/urandom", O_RDONLY); - b32 Result = (read(DevRandom, Dest.Data, Dest.Count) == Count); + b32 Result = (read(DevRandom, Dest, Count) == Count); close(DevRandom); return Result; @@ -179,6 +186,7 @@ static void InitializeOSPlatform(void) { GlobalOSPlatform.Initialized = true; GlobalOSPlatform.CPUTimerFreq = EstimateCPUTimerFreq(); + GlobalOSPlatform.LargePageSize = 2048 * 1024; } } @@ -252,4 +260,4 @@ inline void FillWithRandomBytes(buffer Dest) ReadOSRandomBytes(ReadCount, Dest.Data + AtOffset); AtOffset += ReadCount; } -} \ No newline at end of file +}