Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package primesieve for openSUSE:Factory checked in at 2023-05-13 17:18:05 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/primesieve (Old) and /work/SRC/openSUSE:Factory/.primesieve.new.1533 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "primesieve" Sat May 13 17:18:05 2023 rev:9 rq:1086888 version:11.1 Changes: -------- --- /work/SRC/openSUSE:Factory/primesieve/primesieve.changes 2022-12-07 17:37:37.177411253 +0100 +++ /work/SRC/openSUSE:Factory/.primesieve.new.1533/primesieve.changes 2023-05-13 17:18:09.842561586 +0200 @@ -1,0 +2,8 @@ +Sat May 13 08:05:00 UTC 2023 - Kim Walisch <kim.wali...@gmail.com> + +- Update to primesieve-11.1 +- Vectorized pre-sieving algorithm using x64 SSE2 and ARM NEON +- Added POPCNT algorithm for x64 & AArch64 +- Fix -Wstrict-prototypes warnings + +------------------------------------------------------------------- Old: ---- primesieve-11.0.tar.gz New: ---- primesieve-11.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ primesieve.spec ++++++ --- /var/tmp/diff_new_pack.pxfpqR/_old 2023-05-13 17:18:10.330564393 +0200 +++ /var/tmp/diff_new_pack.pxfpqR/_new 2023-05-13 17:18:10.338564440 +0200 @@ -17,7 +17,7 @@ Name: primesieve -Version: 11.0 +Version: 11.1 Release: 0 Summary: A prime number generator License: BSD-2-Clause ++++++ primesieve-11.0.tar.gz -> primesieve-11.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/CMakeLists.txt new/primesieve-11.1/CMakeLists.txt --- old/primesieve-11.0/CMakeLists.txt 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/CMakeLists.txt 2023-05-12 11:38:28.000000000 +0200 @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.4...3.22) project(primesieve CXX) -set(PRIMESIEVE_VERSION "11.0") -set(PRIMESIEVE_SOVERSION "11.0.0") +set(PRIMESIEVE_VERSION "11.1") +set(PRIMESIEVE_SOVERSION "11.1.0") # Build options ###################################################### @@ -23,8 +23,9 @@ option(BUILD_SHARED_LIBS "Build shared libprimesieve" OFF) endif() -option(WITH_MULTIARCH "Enable runtime dispatching to fastest supported CPU instruction set" ON) -option(WITH_MSVC_CRT_STATIC "Link primesieve.lib with /MT instead of the default /MD" OFF) +option(WITH_AUTO_VECTORIZATION "Enable compiler auto-vectorization" ON) +option(WITH_MULTIARCH "Enable runtime dispatching to fastest supported CPU instruction set" ON) +option(WITH_MSVC_CRT_STATIC "Link primesieve.lib with /MT instead of the default /MD" OFF) # libprimesieve sanity check ######################################### @@ -94,6 +95,12 @@ include("${PROJECT_SOURCE_DIR}/cmake/libatomic.cmake") +# Check if compiler supports auto vectorization ###################### + +if(WITH_AUTO_VECTORIZATION) + include("${PROJECT_SOURCE_DIR}/cmake/auto_vectorization.cmake") +endif() + # Check if compiler supports x64 multiarch ########################### if(WITH_MULTIARCH) @@ -113,6 +120,7 @@ list(GET SOVERSION_LIST 0 PRIMESIEVE_SOVERSION_MAJOR) set_target_properties(libprimesieve PROPERTIES SOVERSION ${PRIMESIEVE_SOVERSION_MAJOR}) set_target_properties(libprimesieve PROPERTIES VERSION ${PRIMESIEVE_SOVERSION}) + target_compile_options(libprimesieve PRIVATE ${FTREE_VECTORIZE_FLAG} ${FVECT_COST_MODEL_FLAG}) if(multiarch_popcnt_bmi) target_compile_definitions(libprimesieve PRIVATE "MULTIARCH_POPCNT_BMI") @@ -159,6 +167,7 @@ add_library(libprimesieve-static STATIC ${LIB_SRC}) set_target_properties(libprimesieve-static PROPERTIES OUTPUT_NAME primesieve) target_link_libraries(libprimesieve-static PRIVATE Threads::Threads ${LIBATOMIC}) + target_compile_options(libprimesieve-static PRIVATE ${FTREE_VECTORIZE_FLAG} ${FVECT_COST_MODEL_FLAG}) if(multiarch_popcnt_bmi) target_compile_definitions(libprimesieve-static PRIVATE "MULTIARCH_POPCNT_BMI") @@ -311,7 +320,7 @@ DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) endif() -# Install primesieve.pc (pkg-config) ################################# +# Install primesieve.pc (pkgconf) #################################### configure_file(primesieve.pc.in primesieve.pc @ONLY) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/COPYING new/primesieve-11.1/COPYING --- old/primesieve-11.0/COPYING 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/COPYING 2023-05-12 11:38:28.000000000 +0200 @@ -1,6 +1,6 @@ BSD 2-Clause License -Copyright (c) 2010 - 2022, Kim Walisch. +Copyright (c) 2010 - 2023, Kim Walisch. All rights reserved. Redistribution and use in source and binary forms, with or without diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/ChangeLog new/primesieve-11.1/ChangeLog --- old/primesieve-11.0/ChangeLog 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/ChangeLog 2023-05-12 11:38:28.000000000 +0200 @@ -1,3 +1,25 @@ +Changes in version 11.1, 12/05/2023 +=================================== + +When primesieve is distributed via distro package managers, it is often +not compiled using the highest optimization level -O3. Because of this +primesieve's pre-sieving algorithm was not auto-vectorized in many +cases. As a workaround for this issue I have now manually vectorized +the pre-sieving algorithm for x64 CPUs (using portable SSE2) and for +ARM64 CPUs (using portable ARM NEON). This can improve performance by +up to 40%. + +* PreSieve.cpp: Vectorize loop using x64 SSE2 & ARM NEON. +* popcount.cpp: Add POPCNT algorithm for x64 & AArch64. +* primesieve.h: Fix -Wstrict-prototypes warning. +* examples/c/*.c: Fix -Wstrict-prototypes warning. +* test/*.c: Fix -Wstrict-prototypes warning. +* CMakeLists.txt: New WITH_AUTO_VECTORIZATION option (with default ON). +* cmake/auto_vectorize.cmake: Enable auto-vectorization if the compiler + supports it. +* scripts/build_mingw64_x64.sh: Build primesieve x64 release binary. +* scripts/build_mingw64_arm64.sh: Build primesieve arm64 release binary. + Changes in version 11.0, 02/12/2022 =================================== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/README.md new/primesieve-11.1/README.md --- old/primesieve-11.0/README.md 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/README.md 2023-05-12 11:38:28.000000000 +0200 @@ -42,10 +42,6 @@ <td><code>sudo pacman -S primesieve</code></td> </tr> <tr> - <td><b>Chocolatey:</b></td> - <td><code>choco install primesieve</code></td> - </tr> - <tr> <td><b>Debian/Ubuntu:</b></td> <td><code>sudo apt install primesieve</code></td> </tr> @@ -124,8 +120,8 @@ ```sh cmake . -make -j -sudo make install +cmake --build . --parallel +sudo cmake --install . sudo ldconfig ``` @@ -215,7 +211,7 @@ </tr> <tr> <td><b>Python:</b></td> - <td><a href="https://github.com/kimwalisch/primesieve-python">primesieve-python</a></td> + <td><a href="https://github.com/shlomif/primesieve-python">primesieve-python</a></td> </tr> <tr> <td><b>Raku:</b></td> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/cmake/auto_vectorization.cmake new/primesieve-11.1/cmake/auto_vectorization.cmake --- old/primesieve-11.0/cmake/auto_vectorization.cmake 1970-01-01 01:00:00.000000000 +0100 +++ new/primesieve-11.1/cmake/auto_vectorization.cmake 2023-05-12 11:38:28.000000000 +0200 @@ -0,0 +1,29 @@ +# The andBuffers() function in PreSieve.cpp is important for +# performance and therefore it is important that this function is +# auto-vectorized by the compiler. For GCC & Clang we can enable +# auto vectorization using -ftree-vectorize. + +# GCC/Clang enable auto-vectorization with -O2 and -O3, but for -O2 +# GCC uses the "very-cheap" cost model which prevents our andBuffers() +# function from getting auto vectorized. But compiling with e.g. +# "-O2 -ftree-vectorize -fvect-cost-model=dynamic" fixes this issue. + +include(CheckCXXCompilerFlag) + +cmake_push_check_state() +set(CMAKE_REQUIRED_FLAGS -Werror) +check_cxx_compiler_flag(-ftree-vectorize ftree_vectorize) +cmake_pop_check_state() + +if(ftree_vectorize) + set(FTREE_VECTORIZE_FLAG "-ftree-vectorize") + + cmake_push_check_state() + set(CMAKE_REQUIRED_FLAGS -Werror) + check_cxx_compiler_flag(-fvect-cost-model=dynamic fvect_cost_model) + cmake_pop_check_state() + + if(fvect_cost_model) + set(FVECT_COST_MODEL_FLAG "-fvect-cost-model=dynamic") + endif() +endif() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/doc/BUILD.md new/primesieve-11.1/doc/BUILD.md --- old/primesieve-11.0/doc/BUILD.md 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/doc/BUILD.md 2023-05-12 11:38:28.000000000 +0200 @@ -33,8 +33,8 @@ ```bash cmake . -make -j -sudo make install +cmake --build . --parallel +sudo cmake --install . sudo ldconfig ``` @@ -44,8 +44,7 @@ ```bash cmake -G "Unix Makefiles" . -make -j -sudo make install +cmake --build . --parallel ``` ## Microsoft Visual C++ @@ -61,7 +60,7 @@ cmake --build . --config Release # Optionally install using Admin shell -cmake --build . --config Release --target install +cmake --install . --config Release ``` ## CMake configure options @@ -79,8 +78,9 @@ option(BUILD_EXAMPLES "Build example programs" OFF) option(BUILD_TESTS "Build test programs" OFF) -option(WITH_MULTIARCH "Enable runtime dispatching to fastest supported CPU instruction set" ON) -option(WITH_MSVC_CRT_STATIC "Link primesieve.lib with /MT instead of the default /MD" OFF) +option(WITH_AUTO_VECTORIZATION "Enable compiler auto-vectorization" ON) +option(WITH_MULTIARCH "Enable runtime dispatching to fastest supported CPU instruction set" ON) +option(WITH_MSVC_CRT_STATIC "Link primesieve.lib with /MT instead of the default /MD" OFF) ``` ## Run the tests @@ -89,17 +89,22 @@ ```bash cmake -DBUILD_TESTS=ON . -make -j +cmake --build . --parallel ctest ``` +For developers hacking on primesieve's source code the +[test/README.md](../test/README.md) document contains more information +about primesieve testing such as testing in debug mode and testing +using GCC/Clang sanitizers. + ## C/C++ examples Open a terminal, cd into the primesieve directory and run: ```bash cmake -DBUILD_EXAMPLES=ON . -make -j +cmake --build . --parallel ``` ## API documentation @@ -110,7 +115,7 @@ ```bash cmake -DBUILD_DOC=ON . -make doc +cmake --build . --target doc ``` ## Man page regeneration @@ -124,5 +129,5 @@ ```bash # Build man page using a2x program (asciidoc package) cmake -DBUILD_MANPAGE=ON . -make -j +cmake --build . --parallel ``` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/doc/CPP_API.md new/primesieve-11.1/doc/CPP_API.md --- old/primesieve-11.0/doc/CPP_API.md 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/doc/CPP_API.md 2023-05-12 11:38:28.000000000 +0200 @@ -32,6 +32,7 @@ * [Performance tips](#performance-tips) * [libprimesieve multi-threading](#libprimesieve-multi-threading) * [Compiling and linking](#compiling-and-linking) +* [pkgconf support](#pkgconf-support) * [CMake support](#cmake-support) ## ```primesieve::iterator::next_prime()``` @@ -456,6 +457,17 @@ cl /O2 /EHsc /MD primes.cpp /I "path\to\primesieve\include" /link "path\to\primesieve.lib" ``` +# pkgconf support + +primesieve also has support for the +[pkgconf](https://github.com/pkgconf/pkgconf) program which +allows to easily compile C and C++ programs depending on libprimesieve +without having to care about the library and include paths: + +```sh +c++ -O3 main.cpp -o main $(pkgconf --libs --cflags primesieve) +``` + # CMake support If you are using the CMake build system to compile your program and diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/doc/C_API.md new/primesieve-11.1/doc/C_API.md --- old/primesieve-11.0/doc/C_API.md 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/doc/C_API.md 2023-05-12 11:38:28.000000000 +0200 @@ -32,6 +32,7 @@ * [Performance tips](#performance-tips) * [libprimesieve multi-threading](#libprimesieve-multi-threading) * [Compiling and linking](#compiling-and-linking) +* [pkgconf support](#pkgconf-support) * [CMake support](#cmake-support) ## ```primesieve_next_prime()``` @@ -54,7 +55,7 @@ #include <inttypes.h> #include <stdio.h> -int main() +int main(void) { primesieve_iterator it; primesieve_init(&it); @@ -95,7 +96,7 @@ #include <inttypes.h> #include <stdio.h> -int main() +int main(void) { primesieve_iterator it; primesieve_init(&it); @@ -137,7 +138,7 @@ #include <inttypes.h> #include <stdio.h> -int main() +int main(void) { primesieve_iterator it; primesieve_init(&it); @@ -173,7 +174,7 @@ #include <inttypes.h> #include <stdio.h> -int main() +int main(void) { primesieve_iterator it; primesieve_init(&it); @@ -205,7 +206,7 @@ #include <primesieve.h> #include <stdio.h> -int main() +int main(void) { uint64_t start = 0; uint64_t stop = 1000; @@ -236,7 +237,7 @@ #include <primesieve.h> #include <stdio.h> -int main() +int main(void) { uint64_t n = 1000; uint64_t start = 0; @@ -264,7 +265,7 @@ #include <inttypes.h> #include <stdio.h> -int main() +int main(void) { /* primesieve_count_primes(start, stop) */ uint64_t count = primesieve_count_primes(0, 1000); @@ -286,7 +287,7 @@ #include <inttypes.h> #include <stdio.h> -int main() +int main(void) { /* primesieve_nth_prime(n, start) */ uint64_t n = 25; @@ -311,7 +312,7 @@ #include <inttypes.h> #include <stdio.h> -int main() +int main(void) { uint64_t count = primesieve_count_primes(0, 1000); @@ -449,7 +450,7 @@ #include <stdio.h> #include <omp.h> -int main() +int main(void) { uint64_t sum = 0; uint64_t dist = 1e10; @@ -519,6 +520,17 @@ cl /O2 /EHsc /MD primes.c /I "path\to\primesieve\include" /link "path\to\primesieve.lib" ``` +# pkgconf support + +primesieve also has support for the +[pkgconf](https://github.com/pkgconf/pkgconf) program which +allows to easily compile C and C++ programs depending on libprimesieve +without having to care about the library and include paths: + +```sh +cc -O3 main.c -o main $(pkgconf --libs --cflags primesieve) +``` + # CMake support If you are using the CMake build system to compile your program and diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/doc/RELEASE.md new/primesieve-11.1/doc/RELEASE.md --- old/primesieve-11.0/doc/RELEASE.md 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/doc/RELEASE.md 2023-05-12 11:38:28.000000000 +0200 @@ -1,4 +1,5 @@ # How to release a new primesieve version * Update the [ChangeLog](../ChangeLog) file. -* Run ```scripts/update_version.sh``` in the root directory of the primesieve git repo to update the version number. +* Run ```scripts/update_version.sh``` in the root directory of the primesieve git repo to update the version number. This script takes the new version number as a parameter e.g.: ```scripts/./update_version.sh 1.2``` +* Go to the [GitHub website and do the release](https://github.com/kimwalisch/primesieve/releases). The release title should be primesieve-X.Y and the tag name should be vX.Y (e.g. primesieve-1.0 and v1.0). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/examples/README.md new/primesieve-11.1/examples/README.md --- old/primesieve-11.0/examples/README.md 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/examples/README.md 2023-05-12 11:38:28.000000000 +0200 @@ -11,5 +11,5 @@ ```sh cmake -DBUILD_EXAMPLES=ON . -make -j +cmake --build . --parallel ``` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/examples/c/count_primes.c new/primesieve-11.1/examples/c/count_primes.c --- old/primesieve-11.0/examples/c/count_primes.c 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/examples/c/count_primes.c 2023-05-12 11:38:28.000000000 +0200 @@ -5,7 +5,7 @@ #include <inttypes.h> #include <stdio.h> -int main() +int main(void) { uint64_t count = primesieve_count_primes(0, 1000); printf("Primes <= 1000: %" PRIu64 "\n", count); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/examples/c/primes_array.c new/primesieve-11.1/examples/c/primes_array.c --- old/primesieve-11.0/examples/c/primes_array.c 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/examples/c/primes_array.c 2023-05-12 11:38:28.000000000 +0200 @@ -4,7 +4,7 @@ #include <primesieve.h> #include <stdio.h> -int main() +int main(void) { uint64_t start = 0; uint64_t stop = 1000; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/include/primesieve.h new/primesieve-11.1/include/primesieve.h --- old/primesieve-11.0/include/primesieve.h 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/include/primesieve.h 2023-05-12 11:38:28.000000000 +0200 @@ -7,7 +7,7 @@ * standard error stream. libprimesieve also sets the C errno * variable to EDOM if an error occurs. * - * Copyright (C) 2022 Kim Walisch, <kim.wali...@gmail.com> + * Copyright (C) 2023 Kim Walisch, <kim.wali...@gmail.com> * * This file is distributed under the BSD License. */ @@ -15,9 +15,9 @@ #ifndef PRIMESIEVE_H #define PRIMESIEVE_H -#define PRIMESIEVE_VERSION "11.0" +#define PRIMESIEVE_VERSION "11.1" #define PRIMESIEVE_VERSION_MAJOR 11 -#define PRIMESIEVE_VERSION_MINOR 0 +#define PRIMESIEVE_VERSION_MINOR 1 #include <primesieve/iterator.h> @@ -209,13 +209,13 @@ * Returns the largest valid stop number for primesieve. * @return 2^64-1 (UINT64_MAX). */ -uint64_t primesieve_get_max_stop(); +uint64_t primesieve_get_max_stop(void); /** Get the current set sieve size in KiB */ -int primesieve_get_sieve_size(); +int primesieve_get_sieve_size(void); /** Get the current set number of threads */ -int primesieve_get_num_threads(); +int primesieve_get_num_threads(void); /** * Set the sieve size in KiB (kibibyte). @@ -240,7 +240,7 @@ void primesieve_free(void* primes); /** Get the primesieve version number, in the form âi.jâ */ -const char* primesieve_version(); +const char* primesieve_version(void); #ifdef __cplusplus } /* extern "C" */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/include/primesieve.hpp new/primesieve-11.1/include/primesieve.hpp --- old/primesieve-11.0/include/primesieve.hpp 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/include/primesieve.hpp 2023-05-12 11:38:28.000000000 +0200 @@ -5,7 +5,7 @@ /// primesieve::primesieve_error exception (derived form /// std::runtime_error) is thrown. /// -/// Copyright (C) 2022 Kim Walisch, <kim.wali...@gmail.com> +/// Copyright (C) 2023 Kim Walisch, <kim.wali...@gmail.com> /// /// This file is distributed under the BSD License. /// @@ -13,9 +13,9 @@ #ifndef PRIMESIEVE_HPP #define PRIMESIEVE_HPP -#define PRIMESIEVE_VERSION "11.0" +#define PRIMESIEVE_VERSION "11.1" #define PRIMESIEVE_VERSION_MAJOR 11 -#define PRIMESIEVE_VERSION_MINOR 0 +#define PRIMESIEVE_VERSION_MINOR 1 #include <primesieve/iterator.hpp> #include <primesieve/primesieve_error.hpp> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/scripts/build_mingw64_arm64.sh new/primesieve-11.1/scripts/build_mingw64_arm64.sh --- old/primesieve-11.0/scripts/build_mingw64_arm64.sh 1970-01-01 01:00:00.000000000 +0100 +++ new/primesieve-11.1/scripts/build_mingw64_arm64.sh 2023-05-12 11:38:28.000000000 +0200 @@ -0,0 +1,99 @@ +#!/bin/bash + +# Usage: scripts/build_mingw64_arm64.sh +# Builds a primesieve release binary that is statically linked +# and ready for distribution. + +# === Prerequisites arm64 === +# 1) Install a trial version of both Parallels & Windows on a MacBook ARM64. +# 2) No need to purchase/register Parallels & Windows, keep using the trial version. +# 3) Install MSYS2 x64 +# 4) Open C:/msys64/clangarm64.exe +# 5) pacman -Syu (exit then run it again) +# 6) pacman -S mingw-w64-clang-aarch64-clang mingw-w64-clang-aarch64-openmp make git zip unzip +# 7) git clone https://github.com/kimwalisch/primesieve.git +# 8) scripts/build_mingw64_arm64.sh + +# Exit if any error occurs +set -e + +rm -rf build* + +#################################################################### + +FULL_DATE=$(date +'%B %d, %Y') +YEAR=$(date +'%Y') + +cd include +VERSION=$(grep "PRIMESIEVE_VERSION " primesieve.hpp | cut -f2 -d'"') +cd .. + +#################################################################### + +handle_error() { + echo "" + echo "Error: $1" + exit 1 +} + +#################################################################### + +# The repo must no have any uncommited changes as we +# switch to another branch during the script. +git diff --exit-code > /dev/null || handle_error "repo must not have any uncommitted changes" + +# Build primesieve binary ########################################## + +git pull +mkdir build-release +cd build-release + +clang++ -static -O3 -flto -DNDEBUG -D_WIN32_WINNT=0x0A00 -Wall -Wextra -pedantic -I ../include ../src/*.cpp ../src/app/*.cpp -o primesieve.exe +strip primesieve.exe + +# Create a release zip archive +wget https://github.com/kimwalisch/primesieve/releases/download/v11.0/primesieve-11.0-win-arm64.zip +unzip primesieve-11.0-win-arm64.zip -d primesieve-$VERSION-win-arm64 +rm primesieve-11.0-win-arm64.zip + +echo "" +echo "" +echo "Old file size: $(ls -l --block-size=K primesieve-$VERSION-win-arm64/primesieve.exe)" +echo "New file size: $(ls -l --block-size=K primesieve.exe)" +echo "" +echo "" + +mv -f primesieve.exe primesieve-$VERSION-win-arm64 +cd primesieve-$VERSION-win-arm64 +sed -i "1 s/.*/primesieve $VERSION/" README.txt +sed -i "2 s/.*/$FULL_DATE/" README.txt +sed -i "3 s/.*/Copyright \(c\) 2010 - $YEAR, Kim Walisch\./" COPYING + +# Verify sed has worked correctly +[ "$(sed -n '1p' < README.txt)" = "primesieve $VERSION" ] || handle_error "failed updating README.txt" +[ "$(sed -n '2p' < README.txt)" = "$FULL_DATE" ] || handle_error "failed updating README.txt" +[ "$(sed -n '3p' < COPYING)" = "Copyright (c) 2010 - $YEAR, Kim Walisch." ] || handle_error "failed updating COPYING" + +zip primesieve-$VERSION-win-arm64.zip primesieve.exe README.txt COPYING +cp primesieve-$VERSION-win-arm64.zip .. + +./primesieve -v +echo "" +echo "" + +./primesieve --cpu-info +echo "" +echo "" + +./primesieve --test +echo "" +echo "" + +./primesieve 1e11 +echo "" +echo "" + +#################################################################### + +echo "Release binary built successfully!" +cd .. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/scripts/build_mingw64_x64.sh new/primesieve-11.1/scripts/build_mingw64_x64.sh --- old/primesieve-11.0/scripts/build_mingw64_x64.sh 1970-01-01 01:00:00.000000000 +0100 +++ new/primesieve-11.1/scripts/build_mingw64_x64.sh 2023-05-12 11:38:28.000000000 +0200 @@ -0,0 +1,96 @@ +#!/bin/bash + +# Usage: scripts/build_mingw64_x64.sh +# Builds a primesieve release binary that is statically linked +# and ready for distribution. + +# === Prerequisites x64 === +# 1) Install MSYS2 x64 +# 2) pacman -Syu (exit then run it again) +# 3) pacman -S --needed base-devel mingw-w64-x86_64-toolchain mingw-w64-x86_64-cmake zip unzip git +# 4) git clone https://github.com/kimwalisch/primesieve.git +# 5) scripts/build_mingw64_x64.sh + +# Exit if any error occurs +set -e + +rm -rf build* + +#################################################################### + +FULL_DATE=$(date +'%B %d, %Y') +YEAR=$(date +'%Y') + +cd include +VERSION=$(grep "PRIMESIEVE_VERSION " primesieve.hpp | cut -f2 -d'"') +cd .. + +#################################################################### + +handle_error() { + echo "" + echo "Error: $1" + exit 1 +} + +#################################################################### + +# The repo must no have any uncommited changes as we +# switch to another branch during the script. +git diff --exit-code > /dev/null || handle_error "repo must not have any uncommitted changes" + +# Build primesieve binary ########################################## + +git pull +mkdir build-release +cd build-release + +g++ -static -O3 -flto -DNDEBUG -D_WIN32_WINNT=0x0A00 -Wall -Wextra -pedantic -I ../include ../src/*.cpp ../src/app/*.cpp -o primesieve.exe +strip primesieve.exe + +# Create a release zip archive +wget https://github.com/kimwalisch/primesieve/releases/download/v11.0/primesieve-11.0-win-x64.zip +unzip primesieve-11.0-win-x64.zip -d primesieve-$VERSION-win-x64 +rm primesieve-11.0-win-x64.zip + +echo "" +echo "" +echo "Old file size: $(ls -l --block-size=K primesieve-$VERSION-win-x64/primesieve.exe)" +echo "New file size: $(ls -l --block-size=K primesieve.exe)" +echo "" +echo "" + +mv -f primesieve.exe primesieve-$VERSION-win-x64 +cd primesieve-$VERSION-win-x64 +sed -i "1 s/.*/primesieve $VERSION/" README.txt +sed -i "2 s/.*/$FULL_DATE/" README.txt +sed -i "3 s/.*/Copyright \(c\) 2010 - $YEAR, Kim Walisch\./" COPYING + +# Verify sed has worked correctly +[ "$(sed -n '1p' < README.txt)" = "primesieve $VERSION" ] || handle_error "failed updating README.txt" +[ "$(sed -n '2p' < README.txt)" = "$FULL_DATE" ] || handle_error "failed updating README.txt" +[ "$(sed -n '3p' < COPYING)" = "Copyright (c) 2010 - $YEAR, Kim Walisch." ] || handle_error "failed updating COPYING" + +zip primesieve-$VERSION-win-x64.zip primesieve.exe README.txt COPYING +cp primesieve-$VERSION-win-x64.zip .. + +./primesieve -v +echo "" +echo "" + +./primesieve --cpu-info +echo "" +echo "" + +./primesieve --test +echo "" +echo "" + +./primesieve 1e11 +echo "" +echo "" + +#################################################################### + +echo "Release binary built successfully!" +cd .. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/scripts/build_msvc.bat new/primesieve-11.1/scripts/build_msvc.bat --- old/primesieve-11.0/scripts/build_msvc.bat 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/scripts/build_msvc.bat 1970-01-01 01:00:00.000000000 +0100 @@ -1,22 +0,0 @@ -@ECHO OFF - -:: === Usage === -:: This script builds a primesieve binary that is suitable for -:: distribution on the internet. The built primesieve binary -:: will only depend on kernel32.dll. -:: -:: 1) Open a Visual Studio Command Prompt -:: 2) cd into primesieve repo -:: 3) Run: scripts/build_msvc.bat - -rmdir /s /q build-msvc -mkdir build-msvc -cd build-msvc - -cl /O2 /EHsc /W3 /D NDEBUG /I ../include ../src/*.cpp ../src/app/*.cpp /Feprimesieve.exe - -echo "" -primesieve.exe --version - -echo "" -primesieve.exe --test diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/scripts/update_version.sh new/primesieve-11.1/scripts/update_version.sh --- old/primesieve-11.0/scripts/update_version.sh 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/scripts/update_version.sh 2023-05-12 11:38:28.000000000 +0200 @@ -74,7 +74,7 @@ # Update version number in man page echo "" cmake . -make -j +cmake --build . --parallel echo "" echo "Version has been updated!" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/src/PreSieve.cpp new/primesieve-11.1/src/PreSieve.cpp --- old/primesieve-11.0/src/PreSieve.cpp 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/src/PreSieve.cpp 2023-05-12 11:38:28.000000000 +0200 @@ -20,7 +20,7 @@ /// Pre-sieving provides a speedup of up to 30% when /// sieving the primes < 10^10 using primesieve. /// -/// Copyright (C) 2022 Kim Walisch, <kim.wali...@gmail.com> +/// Copyright (C) 2023 Kim Walisch, <kim.wali...@gmail.com> /// /// This file is distributed under the BSD License. See the COPYING /// file in the top level directory. @@ -35,6 +35,20 @@ #include <cmath> #include <initializer_list> +/// All x64 CPUs support the SSE2 vector instruction set +#if defined(__SSE2__) && \ + __has_include(<emmintrin.h>) + #include <emmintrin.h> + #define HAS_SSE2 +#endif + +// All ARM64 CPUs support the NEON vector instruction set +#if (defined(__ARM_NEON) || defined(__aarch64__)) && \ + __has_include(<arm_neon.h>) + #include <arm_neon.h> + #define HAS_ARM_NEON +#endif + using std::copy_n; using primesieve::pod_array; @@ -170,23 +184,116 @@ (79 * 97) * 30 + (83 * 89) * 30; -void andBuffers(const uint8_t* __restrict buf1, +#if defined(HAS_SSE2) + +/// Since compiler auto-vectorization is not 100% reliable, we have +/// manually vectorized the andBuffers() function for x64 CPUs. +/// This algorithm is portable since all x64 CPUs support the SSE2 +/// instruction set. +/// +void andBuffers(const uint8_t* __restrict buf0, + const uint8_t* __restrict buf1, + const uint8_t* __restrict buf2, + const uint8_t* __restrict buf3, + const uint8_t* __restrict buf4, + const uint8_t* __restrict buf5, + const uint8_t* __restrict buf6, + const uint8_t* __restrict buf7, + uint8_t* __restrict output, + std::size_t bytes) +{ + std::size_t i = 0; + std::size_t limit = bytes - bytes % sizeof(__m128i); + + // Note that I also tried vectorizing this algorithm using AVX2 + // which has double the vector width compared to SSE2, but this did + // not provide any speedup. On average, this loop processes only + // 2192 bytes, hence there aren't many vector loop iterations and + // by increasing the vector width this also increases the number of + // scalar loop iterations after the vector loop finishes which + // could potentially even become a bottleneck. + for (; i < limit; i += sizeof(__m128i)) + { + _mm_storeu_si128((__m128i*) &output[i], + _mm_and_si128( + _mm_and_si128( + _mm_and_si128(_mm_loadu_si128((const __m128i*) &buf0[i]), _mm_loadu_si128((const __m128i*) &buf1[i])), + _mm_and_si128(_mm_loadu_si128((const __m128i*) &buf2[i]), _mm_loadu_si128((const __m128i*) &buf3[i]))), + _mm_and_si128( + _mm_and_si128(_mm_loadu_si128((const __m128i*) &buf4[i]), _mm_loadu_si128((const __m128i*) &buf5[i])), + _mm_and_si128(_mm_loadu_si128((const __m128i*) &buf6[i]), _mm_loadu_si128((const __m128i*) &buf7[i]))))); + } + + for (; i < bytes; i++) + output[i] = buf0[i] & buf1[i] & buf2[i] & buf3[i] & + buf4[i] & buf5[i] & buf6[i] & buf7[i]; +} + +#elif defined(HAS_ARM_NEON) + +/// Homebrew compiles its C/C++ packages on macOS using Clang -Os +/// (instead of -O2 or -O3) which does not auto-vectorize our simple +/// loop with Bitwise AND. If this loop is not vectorized this +/// deteriorates the performance of primesieve by up to 40%. As a +/// workaround for this Homebrew issue we have manually vectorized +/// the Bitwise AND loop using ARM NEON. +/// +void andBuffers(const uint8_t* __restrict buf0, + const uint8_t* __restrict buf1, const uint8_t* __restrict buf2, const uint8_t* __restrict buf3, const uint8_t* __restrict buf4, const uint8_t* __restrict buf5, const uint8_t* __restrict buf6, const uint8_t* __restrict buf7, - const uint8_t* __restrict buf8, uint8_t* __restrict output, std::size_t bytes) { - // This loop should be auto-vectorized + std::size_t i = 0; + std::size_t limit = bytes - bytes % sizeof(uint8x16_t); + + for (; i < limit; i += sizeof(uint8x16_t)) + { + vst1q_u8(&output[i], + vandq_u8( + vandq_u8( + vandq_u8(vld1q_u8(&buf0[i]), vld1q_u8(&buf1[i])), + vandq_u8(vld1q_u8(&buf2[i]), vld1q_u8(&buf3[i]))), + vandq_u8( + vandq_u8(vld1q_u8(&buf4[i]), vld1q_u8(&buf5[i])), + vandq_u8(vld1q_u8(&buf6[i]), vld1q_u8(&buf7[i]))))); + } + + for (; i < bytes; i++) + output[i] = buf0[i] & buf1[i] & buf2[i] & buf3[i] & + buf4[i] & buf5[i] & buf6[i] & buf7[i]; +} + +#else + +void andBuffers(const uint8_t* __restrict buf0, + const uint8_t* __restrict buf1, + const uint8_t* __restrict buf2, + const uint8_t* __restrict buf3, + const uint8_t* __restrict buf4, + const uint8_t* __restrict buf5, + const uint8_t* __restrict buf6, + const uint8_t* __restrict buf7, + uint8_t* __restrict output, + std::size_t bytes) +{ + // This loop will get auto-vectorized if compiled with GCC/Clang + // using -O3. Using GCC -O2 does not auto-vectorize this loop + // because -O2 uses the "very-cheap" vector cost model. To fix + // this issue we enable -ftree-vectorize -fvect-cost-model=dynamic + // if the compiler supports it in auto_vectorization.cmake. for (std::size_t i = 0; i < bytes; i++) - output[i] = buf1[i] & buf2[i] & buf3[i] & buf4[i] - & buf5[i] & buf6[i] & buf7[i] & buf8[i]; + output[i] = buf0[i] & buf1[i] & buf2[i] & buf3[i] & + buf4[i] & buf5[i] & buf6[i] & buf7[i]; } +#endif + } // namespace namespace primesieve { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/src/api-c.cpp new/primesieve-11.1/src/api-c.cpp --- old/primesieve-11.0/src/api-c.cpp 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/src/api-c.cpp 2023-05-12 11:38:28.000000000 +0200 @@ -302,12 +302,12 @@ } } -int primesieve_get_sieve_size() +int primesieve_get_sieve_size(void) { return get_sieve_size(); } -int primesieve_get_num_threads() +int primesieve_get_num_threads(void) { return get_num_threads(); } @@ -322,12 +322,12 @@ set_num_threads(num_threads); } -uint64_t primesieve_get_max_stop() +uint64_t primesieve_get_max_stop(void) { return get_max_stop(); } -const char* primesieve_version() +const char* primesieve_version(void) { return PRIMESIEVE_VERSION; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/src/app/help.cpp new/primesieve-11.1/src/app/help.cpp --- old/primesieve-11.0/src/app/help.cpp 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/src/app/help.cpp 2023-05-12 11:38:28.000000000 +0200 @@ -3,7 +3,7 @@ /// @brief help() and version() functions of the primesieve /// console application. /// -/// Copyright (C) 2022 Kim Walisch, <kim.wali...@gmail.com> +/// Copyright (C) 2023 Kim Walisch, <kim.wali...@gmail.com> /// /// This file is distributed under the BSD License. See the COPYING /// file in the top level directory. @@ -57,7 +57,7 @@ { std::cout << "primesieve " << primesieve::primesieve_version(); std::cout << ", <https://github.com/kimwalisch/primesieve>" << std::endl; - std::cout << "Copyright (C) 2010 - 2022 Kim Walisch" << std::endl; + std::cout << "Copyright (C) 2010 - 2023 Kim Walisch" << std::endl; std::cout << "BSD 2-Clause License <https://opensource.org/licenses/BSD-2-Clause>" << std::endl; std::exit(0); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/src/popcount.cpp new/primesieve-11.1/src/popcount.cpp --- old/primesieve-11.0/src/popcount.cpp 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/src/popcount.cpp 2023-05-12 11:38:28.000000000 +0200 @@ -2,19 +2,7 @@ /// @file popcount.cpp /// @brief Quickly count the number of 1 bits in an array. /// -/// The "Harley-Seal popcount" algorithm that we use is a pure -/// integer algorithm that does not use the POPCNT instruction -/// present on many CPU architectures. There are a few reasons -/// why we do not use the POPCNT instruction here: -/// -/// 1) This algorithm is not really a bottleneck. -/// 2) This algorithm is portable (unlike POPCNT on x64) -/// and very fast, its speed is very close to POPCNT. -/// 3) Recent compilers can autovectorize this loop (e.g -/// using AVX512 on x64 CPUs) in which case this algorithm -/// will even outperform the POPCNT instruction. -/// -/// Copyright (C) 2022 Kim Walisch, <kim.wali...@gmail.com> +/// Copyright (C) 2023 Kim Walisch, <kim.wali...@gmail.com> /// /// This file is distributed under the BSD License. See the COPYING /// file in the top level directory. @@ -24,6 +12,50 @@ #include <primesieve/forward.hpp> #include <stdint.h> +/// For CPU architectures that have a POPCNT instruction, we use +/// that to count the number of 1 bits in the sieve array as +/// this will generally provide the best performance. For CPU +/// architectures without POPCNT we use the portable Harley-Seal +/// popcount algorithm further down. +/// +#if defined(__POPCNT__) /* x64 */ || \ + (defined(__ARM_NEON) || defined(__aarch64__)) + +namespace primesieve { + +uint64_t popcount(const uint64_t* array, uint64_t size) +{ + uint64_t i; + uint64_t limit = size - size % 4; + uint64_t cnt = 0; + + for(i = 0; i < limit; i += 4) + { + cnt += popcnt64(array[i+0]); + cnt += popcnt64(array[i+1]); + cnt += popcnt64(array[i+2]); + cnt += popcnt64(array[i+3]); + } + for(; i < size; i++) + cnt += popcnt64(array[i]); + + return cnt; +} + +} // namespace + +#else + +/// The "Harley-Seal popcount" algorithm that we use is a pure +/// integer algorithm that does not use the POPCNT instruction +/// present on many CPU architectures. +/// +/// 1) This algorithm is portable (unlike POPCNT on x64) +/// and very fast, its speed is very close to POPCNT. +/// 2) Recent compilers can autovectorize this loop (e.g +/// using AVX512 on x64 CPUs) in which case this algorithm +/// will even outperform the POPCNT instruction. + namespace { /// Carry-save adder (CSA). @@ -88,3 +120,5 @@ } } // namespace + +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/test/README.md new/primesieve-11.1/test/README.md --- old/primesieve-11.0/test/README.md 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/test/README.md 2023-05-12 11:38:28.000000000 +0200 @@ -1,10 +1,36 @@ -primesieve testing -================== +# primesieve testing -Run the commands below from the root primesieve directory. +Run the commands below from the primesieve root directory. ```bash -cmake -DBUILD_TESTS=ON . -make -j -make test +cmake . -DBUILD_TESTS=ON +cmake --build . --parallel +ctest +``` + +# Test in debug mode + +When hacking on primesieve's source code, it is best to run its test suite +in debug mode i.e. ```-DCMAKE_BUILD_TYPE=Debug``` because this enables +extensive (but slow) runtime assertions. In case an assertion is triggered, +the file name and line number where the error occurred will be printed to +the screen. This helps to quickly identify newly introduced bugs. + +```bash +# Run commands from primesieve root directory +cmake . -DBUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="-O1 -Wall -Wextra -pedantic" -DCMAKE_C_FLAGS="-O1 -Wall -Wextra -pedantic" +cmake --build . --parallel +ctest --output-on-failure +``` + +# Test using GCC/Clang sanitizers + +Running primesieve's test suite with sanitizers enabled is also very useful +as this helps find undefined behavior bugs and data races. + +```bash +# Run commands from primesieve root directory +cmake . -DBUILD_TESTS=ON -DCMAKE_CXX_FLAGS="-g -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all -fno-omit-frame-pointer -Wall -Wextra -pedantic" -DCMAKE_C_FLAGS="-g -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all -fno-omit-frame-pointer -Wall -Wextra -pedantic" +cmake --build . --parallel +ctest --output-on-failure ``` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/test/clear_primesieve_iterator2.c new/primesieve-11.1/test/clear_primesieve_iterator2.c --- old/primesieve-11.0/test/clear_primesieve_iterator2.c 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/test/clear_primesieve_iterator2.c 2023-05-12 11:38:28.000000000 +0200 @@ -26,7 +26,7 @@ } } -int main() +int main(void) { primesieve_iterator it; primesieve_init(&it); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/test/generate_n_primes2.c new/primesieve-11.1/test/generate_n_primes2.c --- old/primesieve-11.0/test/generate_n_primes2.c 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/test/generate_n_primes2.c 2023-05-12 11:38:28.000000000 +0200 @@ -61,7 +61,7 @@ } } -int main() +int main(void) { size_t i; size_t size = 25; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/test/generate_primes2.c new/primesieve-11.1/test/generate_primes2.c --- old/primesieve-11.0/test/generate_primes2.c 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/test/generate_primes2.c 2023-05-12 11:38:28.000000000 +0200 @@ -61,7 +61,7 @@ } } -int main() +int main(void) { size_t i; size_t size = 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/test/next_prime2.c new/primesieve-11.1/test/next_prime2.c --- old/primesieve-11.0/test/next_prime2.c 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/test/next_prime2.c 2023-05-12 11:38:28.000000000 +0200 @@ -26,7 +26,7 @@ } } -int main() +int main(void) { size_t size = 0; uint64_t* primes = (uint64_t*) primesieve_generate_primes(0, 100000, &size, UINT64_PRIMES); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/test/prev_prime2.c new/primesieve-11.1/test/prev_prime2.c --- old/primesieve-11.0/test/prev_prime2.c 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/test/prev_prime2.c 2023-05-12 11:38:28.000000000 +0200 @@ -26,7 +26,7 @@ } } -int main() +int main(void) { size_t size = 0; uint64_t* primes = (uint64_t*) primesieve_generate_primes(0, 100000, &size, UINT64_PRIMES); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/test/skipto_next_prime.c new/primesieve-11.1/test/skipto_next_prime.c --- old/primesieve-11.0/test/skipto_next_prime.c 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/test/skipto_next_prime.c 2023-05-12 11:38:28.000000000 +0200 @@ -35,7 +35,7 @@ } } -int main() +int main(void) { size_t size = 0; uint64_t* primes = (uint64_t*) primesieve_generate_primes(0, 100000, &size, UINT64_PRIMES); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/primesieve-11.0/test/skipto_prev_prime.c new/primesieve-11.1/test/skipto_prev_prime.c --- old/primesieve-11.0/test/skipto_prev_prime.c 2022-12-02 15:16:26.000000000 +0100 +++ new/primesieve-11.1/test/skipto_prev_prime.c 2023-05-12 11:38:28.000000000 +0200 @@ -35,7 +35,7 @@ } } -int main() +int main(void) { size_t size = 0; uint64_t* primes = (uint64_t*) primesieve_generate_primes(0, 100000, &size, UINT64_PRIMES);