Coder Social home page Coder Social logo

kimwalisch / primesieve Goto Github PK

View Code? Open in Web Editor NEW
933.0 46.0 121.0 18.86 MB

🚀 Fast prime number generator

License: BSD 2-Clause "Simplified" License

Shell 2.23% C 5.45% C++ 88.14% CMake 4.14% Batchfile 0.04%
prime-numbers sieve-of-eratosthenes math eratosthenes primes sieve avx512 neon sse

primesieve's People

Contributors

andersk avatar bunder avatar jgmbenoit avatar jschueller avatar julstrat avatar kimwalisch avatar mkoeppe avatar nipzu avatar ohanar avatar sighingnow avatar zielaj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

primesieve's Issues

[Suggestion] Allow boost multiprecision classes and GMP++ classes

it would be really cool if you could calculate arbitrarily large primes using boost::multiprecision and GMP (Or maybe even templates).

Like a library implementation similar to std::string would be useful. Meaning turning it into a template library but precompiling it for the default argument uint64_t

Add a function to return integer factorization

Here is the API that I would imagine:

std::vector<int> factors;
primesieve::factor(1001, &factors);

which would put the numbers 7, 11, 13 into factors.
I am sure you would know the fastest way to do that using your library.

That would be consistent with the current API for
the generate_primes function:

std::vector<int> primes;
primesieve::generate_primes(1000, &primes);

iOS port

Great prime number generator lib in C/C++ (should be the best). Do you have any plan to support iOS officially? Seems not complicated, some configure/make tweaks maybe? That will be great for using in iOS really. Thanks!

macro for the largest valid stop number for primesieve

Please introduce a macro for the largest valid stop number for primesieve, i.e., the value effectively returned by primesieve_get_max_stop(). This is a C oriented request, I guess, the rational is to allow to set up some macros accordingly at precompile time.
BTW, I noticed that this value is not (2^64-1)-(2^32-1)_10 as written in the API doc, but
(2^64-1)-(2^32-1)_10-1 .

Missing DLLs

Hi, very nice project and it works just fine - but unfortunately my use for it is limited because mostly I need dynamic linking instead of static linking...

ubuntu 1604LTS - pip install primesieve hangs on python 3.7.1 fine in 3.7.0 and 3.7.2

This just hangs when I try to install on python 3.7.1 on ubuntu 1604LTS:

pip install primesieve
Collecting primesieve
  Using cached https://files.pythonhosted.org/packages/43/4f/cd9b85d154bc94eec5d4a8cfdbbf96d0e487cecd46495f86b9d5d481d18d/primesieve-1.4.4.tar.gz
Installing collected packages: primesieve
  Running setup.py install for primesieve ... -

Please create a wheel of it so I do not have to install 10GB of Visual Studio Bloat to compile on windows.

Thanks

Add CpuInfo::hasL1Cache()

The CpuInfo class detects the CPUs' cache sizes. Currently in order to check if the cache size has been detected correctly the following check is used:

size_t size = cpuInfo.l1CacheSize();

// failed to detect L1 cache size
if (size == 0)
  return sieveSize;

The CpuInfo class queries the CPUs' cache sizes from the operating system. I think I should not trust the data from the OS e.g. the OSes implementation might change in 10 years and return the cache size in megabytes instead of kilobytes. Therefore I suggest to add methods to the CpuInfo class that check if the cache sizes from the OS look reasonable:

bool CpuInfo::hasL1Cache() const
{
  return l1CacheSize_ >= (1 << 12) &&
         l1CacheSize_ <= (1 << 30);
}

bool CpuInfo::hasL2Cache() const
{
  return l2CacheSize_ >= (1 << 15) &&
         l2CacheSize_ <= (1 << 30);
}

bool CpuInfo::hasL3Cache() const
{
  return l3CacheSize_ >= (1 << 16) &&
         l3CacheSize_ <= (1ull << 40);
}

Use 256 kilobyte sieve size instead of 32 kilobyte sieve size

Message from hyb:

I just changed some code of primesieve, and now it runs faster for some ranges.
For sieving big interval with sievesize > 256k, the EratSmall algorithm does not fully fit into the L1/L2 data cache.
The default sievesize = 256k is best for current CPUs, you are using 32k.

eratsmall

sieveoferatosthenes

Using project as a dynamic library

Hello, I've wanted to ask if it is possible to compile this project as a dynamic library in windows. I have successfully compiled from source the exe file but i am not sure how to get dll. (I'd like to use it to make a wrapper for C#).

Thanks,
David.

Feature request: iterator move-constructor and move-assignment

The following silly code currently fails to compile:

#include "primesieve.hpp"

int main()
{
  std::vector<primesieve::iterator> vec;
  vec.emplace_back(0, 1000); // Requires move-constructor
  primesieve::iterator it2, it3;
  it2 = std::move(it3); // Requires move-assignment
}

This can be fixed by declaring a default move-constructor and move-assignment operator. Code could be as follows.

In iterator.hpp:

iterator(iterator&&);
iterator& operator=(iterator&&);

In iterator.cpp:

iterator::iterator(iterator&&) = default;
iterator& iterator::operator=(iterator&&) = default;

Although the example is purely silly, I think it would do no harm to provide these functions, and would support some convenient manipulations of iterators. For myself, storing a small collection of iterators in a std::vector would be convenient.

Trouble Compiling on MinGW

Hello,

I am trying to compile on MinGW and the basic build instructions are not working.

If I run:
cmake .
make -j
from the root directory it gives this error:
make: *** No targets specified and no makefile found. Stop.

I was able to work around that by:
cd cmake
cmake .. -G"Unix Makefiles"

However now when I run make -j I am receiving these errors:
$ make -j
Scanning dependencies of target libprimesieve-static
[ 4%] Building CXX object CMakeFiles/libprimesieve-static.dir/src/api-c.cpp.obj
[ 9%] Building CXX object CMakeFiles/libprimesieve-static.dir/src/api.cpp.obj
[ 13%] Building CXX object CMakeFiles/libprimesieve-static.dir/src/CpuInfo.cpp.obj
[ 18%] Building CXX object CMakeFiles/libprimesieve-static.dir/src/EratBig.cpp.obj
[ 22%] Building CXX object CMakeFiles/libprimesieve-static.dir/src/EratMedium.cpp.obj
[ 27%] Building CXX object CMakeFiles/libprimesieve-static.dir/src/EratSmall.cpp.obj
[ 31%] Building CXX object CMakeFiles/libprimesieve-static.dir/src/iterator-c.cpp.obj
[ 36%] Building CXX object CMakeFiles/libprimesieve-static.dir/src/nthPrime.cpp.obj
[ 40%] Building CXX object CMakeFiles/libprimesieve-static.dir/src/iterator.cpp.obj[ 45%]
Building CXX object CMakeFiles/libprimesieve-static.dir/src/ParallelPrimeSieve.cpp.obj
[ 50%] Building CXX object CMakeFiles/libprimesieve-static.dir/src/popcount.cpp.obj
[ 54%] [ 59%] [ 68%] [ 68%] Building CXX object CMakeFiles/libprimesieve-static.dir/src/PrimeSieve.cpp.obj
Building CXX object CMakeFiles/libprimesieve-static.dir/src/PreSieve.cpp.obj[ 72%] Building CXX object CMakeFiles/libprimesieve-static.dir/src/PrimeGenerator.cpp.obj

[ 77%] Building CXX object CMakeFiles/libprimesieve-static.dir/src/SieveOfEratosthenes.cpp.objBuilding CXX object CMakeFiles/libprimesieve-static.dir/src/Wheel.cpp.objBuilding CXX object CMakeFiles/libprimesieve-static.dir/src/SievingPrimes.cpp.obj

C:/InIMi nnfG IifnlWi e/msys/1.0/home/c4n10/primesieve/src/CpuInfo.cpp: In member function 'void primesieve::CpuInfo::initCache()':
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/CpuInfo.cpp:189:36: warning: 'stdcall' attribute only applies to function types [-Wattributes]
lf typedef BOOL (WINAPI LPFN_GLPI)(PSYSTEM_ LOGICAL_PROCESSOR_INFORMATION, PDWORD);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/CpuInfo.cpp:189:36: error: typedef 'LPFN_GLPI' is initialized (use decltype instead)
eiC:/MinGW/msys/1.0/home/c4n10/primesieve/src/CpuInfo.cpp:189:36: error: 'PSYSTEM_LOGICAL_PROCESSOR_INFORMATION' was not declared in this scope
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/CpuInfo.cpp:189:81: error: expected primary-expression befiore ')' token
typedef BOOL (WINAPI LPFN_GLPI)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD);
^
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/CpuInfo.cpp:191:3: error: 'LPFN_GLPI' was not declared in this scope
l LPFN_GLPI glpi = (LPFN_GLPI) GetProcAddress(GetModuleHandle(TEXT("kernel32")), "GetLogicalProcessorInformation");
^~~~~~~~~
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/CpuInfo.cpp:193:8: error: 'glpi' was not declared in this scope
if (!glpi)
^~~~
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/CpuInfon.cpp:197:17: error: 'glpi' was not declared in this scope
glpi(0, &bytes);
^
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/CpuInfo.cpp:203:32: error: 'SYSTEM_LOGICAL_PROCESSOR_INFORMATION' was not declared in this scope
size_t size = bytes / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~ie~~~~~~~~
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/CpuInfo.cpp:204:10: error: the value of 'SYSTEM_LOGICAL_PROCESSOR_INFORMATIONc' is not usable in a constant expression
vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> info(size);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/CpuInfo.cpp:203:32: note: 'SYSTEM_LOGICAL_PROCESSOR_INFORMATION' was not declared 'constexpr'
size_t size = bytes / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
n C:/MinGW/msys/1.0/home/c4n10/primesieve/src/CpuInfo.cpp:204:46: error: type/value mismatch at argument 1 in template parameter list for 'template<class Tp, class Alloc> class std::vector'
l vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> info(size);
^
C:/MicnGW/msys/1.0/home/c4n10/primesieve/src/CpuInfo.cpp:204:46: note: expected a type, got 'SYSTEM_LOGICAL_PROCESSOR_IiuNFORMATION'
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/CpuInfo.cpp:204:46: error: template argument 2 is invalid
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/CpuInfo.cpp:206:20: error: invalid types 'int[int]' for array subscript
l if (!glpi(&info[0], &bytes))
nd ^
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/CpuInfo.cpp:211:15: error: invalid types 'int[size_t {aka unsigned int}]' for array subscript
if (info[i].Relationship == RelationProcessorCore)
^
Cu:/MinGW/msys/1.0/home/c4n10/primesieve/src/CpuInfo.cpp:211:33: error: 'RelationProcessorCore' was not declared in this scope
if (info[i].Relationship == RelationProcessorCore)
^~~~~~~~~~~~~~~~~~~~~
ceC:/MinGW/msys/1.0/home/c4n10/primesieve/src/CpuInfo.cpdp:213:25: error: invalid types 'int[size_t {aka unsigned int}]' for array subscript
auto mask = info[i].ProcessorMask;
^
C:/MinGW/msys/1.0/home/c4n10/primesieve/srlc/CpuInfo.cpp:222:15: error: invalid types 'int[size_t {aka unsigned int}]' for array subscript
if (info[i].Reldaeu tionsddfhip == RelationCache &&
^
C:/MinGW/msys/1.0/home/c4n10/primesieve/src er/CpuInfo.cpp:222:33: error: 'RelationCache'fdo was not declared in this scope
if (info[i].Relationship == RelationCache &&
^~~~~~~~~~~~~
C:/MinGW/msys/1.0/home/c4n10/primesiever m/src/CpuInfo.cpp:223:16: error: invalid types 'int[size_t {aka unsigned int}]' for array subscript
(info[i].Cache.Type == CacheData ||
^
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/CpuInfo.cpp:223:32: error: 'CacheData' was not declared in this scope
of (info[i].Cache.Type == CacheData ||
^~~~~~~~~
mrCC:/MinGW/msys/1.0/home/c4n10/primesieve/src/CpuInfo.cpp:224:16: error: invalid types 'int[size_t {aka unsigned int}]' for array subscript
info[i].Cache. o:Type == CacheUnified))
^
C:/MinGW/msys/1.0/home/c4n10/primeCm/sieve/s: Mrc/CpuInfo.cCip/p:224:32: error: 'CacheUnified' was not declared in this scope
info[i].Cache.Ty:nM/GiMWni/GnmWGs/Wym/ssm/ys1sy./s01//.1h0.o/0mh/eoh/mocem4/enc/14c0n4/1np01r/0ip/mrpeirsmiiemeseviseei/vesevr/ecs//rsacrp/cia/.pPciap-rpca:.l1cl7pe:ppe == CacheUnified))
^~~~~~~~~~~~
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/CpuInfo.cpp:226:17: error: invalid types 'int[size_t {aka unsigned int}]' for array subscript
if (info[i].Cache.Level == 1)
^
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/CpuInfo.c0l:pp:227:30: error: invalid types 'int[size_t {aka unsigned int}]' f:P1or array subscript
l1CacheSize
= info[i].Cache.Size;
^
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/CpuInfo.cpp:228:17: error: invalid types 'int[size_t {aka unsigned int}]' for
r6 array subscript
if (info[i].Cache.Level == 2)
^
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/CpuInfo.cpp:229:30: error: invalid types 'int[size_t {aka unsigned int}]' for array subscript
l2CacheSize
= info[i].Cache.Size;
^
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/CpuInfo.cpp:233:17: error: invalid types 'int[size_t {aka unsigned int}]' for array subscript
if (info[i].Cache.Level == 3 &&
^
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/CpuInfo.cpp:234:17: error: invalid types 'int[size_t {aka unsigned int}]' for array subscript
info[i].Cache.Size > 0)
^
i:Cm0:e:/S
ieCnmake[2]: v:G
* [CMakeFiles/libprimesieve-static.dir/src/CpuInfo.cpp.obj] Error 1e/W.M/
spmake[2]: Gy:W*** Waiting for unfinished jobs....
/2m1:s.0y0:s/
1oC.m:0e///Mhcio4nmnGe1W/0/c/m4psnry1is0m//e1ps.ri0ie/mvheeos/miieen/vccel4/unid1ne0c//lppurrdiiemm/eepssriiieemvveees//iPieanvrceal/luPldaeerl/aPplrrliiemmleePSsriiieemvveeeS./ihPepavpre:a.4lh7lp:ep8l::P4 r7ei:rm8re:oS rie:er vr'eom.ruh:tp ep'x:m'4u 7ti:en8x :'n aeimrner sonpraa:mc ee's mp'uastcteedx ''' sditonde 'sn adnmooeetss p nanacomete 'nasa tmtdey' p aed
ey sp e n
tt d :n :asmmtuedt :ea:x m tulytopecexk
l; o
k s_ t; d
: m u t ^e x ~ l o^
k
_
;

    ^~~~~

make[2]: *** [CMakeFiles/libprimesieve-static.dir/src/api.cpp.obj] Error 1
make[2]: *** [CMakeFiles/libprimesieve-static.dir/src/api-c.cpp.obj] Error 1
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp: In static member function 'static int primesieve::ParallelPrimeSieve::getMaxThreads()':
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:59:22: error: 'thread' has not been declared
return max(1, thread::hardware_concurrency());
^~~~~~
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp: In member function 'virtual void primesieve::ParallelPrimeSieve::sieve()':
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:169:53: error: invalid use of incomplete type 'class std::future<std::vector >'
futures.emplace_back(async(launch::async, task));
^
In file included from C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:21:0:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\future:115:11: note: declaration of 'class std::future<std::vector >'
class future;
^~~~~~
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:172:19: error: invalid use of incomplete type 'class std::future<std::vector >'
counts_ += f.get();
^
In file included from C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:21:0:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\future:115:11: note: declaration of 'class std::future<std::vector >'
class future;
^~~~~~
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp: In member function 'virtual bool primesieve::ParallelPrimeSieve::updateStatus(uint64_t, bool)':
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:194:15: error: 'mutex' was not declared in this scope
unique_lock lock(lock_, defer_lock);
^~~~~
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:194:20: error: template argument 1 is invalid
unique_lock lock(lock_, defer_lock);
^
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:194:27: error: 'lock_' was not declared in this scope
unique_lock lock(lock_, defer_lock);
^~~~~
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:194:44: error: expression list treated as compound expression in initializer [-fpermissive]
unique_lock lock(lock_, defer_lock);
^
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:197:10: error: request for member 'try_lock' in 'lock', which is of non-class type 'int'
lock.try_lock();
^~~~~~~~
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:199:10: error: request for member 'lock' in 'lock', which is of non-class type 'int'
lock.lock();
^~~~
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:201:12: error: request for member 'owns_lock' in 'lock', which is of non-class type 'int'
if (lock.owns_lock())
^~~~~~~~~
In file included from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\vector:69:0,
from C:/MinGW/msys/1.0/home/c4n10/primesieve/include/primesieve/PrimeSieve.hpp:17,
from C:/MinGW/msys/1.0/home/c4n10/primesieve/include/primesieve/ParallelPrimeSieve.hpp:15,
from C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:12:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\vector.tcc: In instantiation of 'void std::vector<_Tp, _Alloc>::reserve(std::vector<_Tp, _Alloc>::size_type) [with _Tp = std::future<std::vector >; _Alloc = std::allocator<std::future<std::vector > >; std::vector<_Tp, _Alloc>::size_type = unsigned int]':
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:166:28: required from here
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\vector.tcc:80:4: error: invalid use of incomplete type 'class std::future<std::vector >'
this->_M_impl._M_end_of_storage
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- this->_M_impl._M_start);
^~~~~~~~~~~~~~~~~~~~~~~~
In file included from C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:21:0:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\future:115:11: note: declaration of 'class std::future<std::vector >'
class future;
^~~~~~
In file included from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\vector:69:0,
from C:/MinGW/msys/1.0/home/c4n10/primesieve/include/primesieve/PrimeSieve.hpp:17,
from C:/MinGW/msys/1.0/home/c4n10/primesieve/include/primesieve/ParallelPrimeSieve.hpp:15,
from C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:12:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\vector.tcc:82:36: error: invalid use of incomplete type 'class std::future<std::vector >'
this->_M_impl._M_finish = __tmp + __old_size;
~~~~~~^~~~~~~~~~~~
In file included from C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:21:0:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\future:115:11: note: declaration of 'class std::future<std::vector >'
class future;
^~~~~~
In file included from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\vector:69:0,
from C:/MinGW/msys/1.0/home/c4n10/primesieve/include/primesieve/PrimeSieve.hpp:17,
from C:/MinGW/msys/1.0/home/c4n10/primesieve/include/primesieve/ParallelPrimeSieve.hpp:15,
from C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:12:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\vector.tcc:83:61: error: invalid use of incomplete type 'class std::future<std::vector >'
this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
~~~~~~~~~~~~~~~~~~~~~~~^~~~~
In file included from C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:21:0:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\future:115:11: note: declaration of 'class std::future<std::vector >'
class future;
^~~~~~
In file included from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algobase.h:67:0,
from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\vector:60,
from C:/MinGW/msys/1.0/home/c4n10/primesieve/include/primesieve/PrimeSieve.hpp:17,
from C:/MinGW/msys/1.0/home/c4n10/primesieve/include/primesieve/ParallelPrimeSieve.hpp:15,
from C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:12:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_iterator.h: In instantiation of '__gnu_cxx::__normal_iterator<_Iterator, _Container>& __gnu_cxx::__normal_iterator<_Iterator, _Container>::operator++() [with _Iterator = std::future<std::vector >; _Container = std::vector<std::future<std::vector > >]':
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:171:20: required from here
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_iterator.h:799:2: error: cannot increment a pointer to incomplete type 'std::future<std::vector >'
++_M_current;
^~~~~~~~~~~~
In file included from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\vector:64:0,
from C:/MinGW/msys/1.0/home/c4n10/primesieve/include/primesieve/PrimeSieve.hpp:17,
from C:/MinGW/msys/1.0/home/c4n10/primesieve/include/primesieve/ParallelPrimeSieve.hpp:15,
from C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:12:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_vector.h: In instantiation of 'std::_Vector_base<_Tp, _Alloc>::~_Vector_base() [with _Tp = std::future<std::vector >; _Alloc = std::allocator<std::future<std::vector > >]':
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_vector.h:259:15: required from 'std::vector<_Tp, _Alloc>::vector() [with _Tp = std::future<std::vector >; _Alloc = std::allocator<std::future<std::vector > >]'
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:165:30: required from here
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_vector.h:161:9: error: invalid use of incomplete type 'class std::future<std::vector >'
{ _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- this->_M_impl._M_start); }
^~~~~~~~~~~~~~~~~~~~~~~~
In file included from C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:21:0:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\future:115:11: note: declaration of 'class std::future<std::vector >'
class future;
^~~~~~
In file included from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\vector:64:0,
from C:/MinGW/msys/1.0/home/c4n10/primesieve/include/primesieve/PrimeSieve.hpp:17,
from C:/MinGW/msys/1.0/home/c4n10/primesieve/include/primesieve/ParallelPrimeSieve.hpp:15,
from C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:12:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_vector.h: In instantiation of 'std::vector<_Tp, _Alloc>::size_type std::vector<_Tp, _Alloc>::capacity() const [with _Tp = std::future<std::vector >; _Alloc = std::allocator<std::future<std::vector > >; std::vector<_Tp, _Alloc>::size_type = unsigned int]':
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\vector.tcc:70:28: required from 'void std::vector<_Tp, _Alloc>::reserve(std::vector<_Tp, _Alloc>::size_type) [with _Tp = std::future<std::vector >; _Alloc = std::allocator<std::future<std::vector > >; std::vector<_Tp, _Alloc>::size_type = unsigned int]'
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:166:28: required from here
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_vector.h:737:5: error: invalid use of incomplete type 'class std::future<std::vector >'
{ return size_type(this->_M_impl._M_end_of_storage
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- this->_M_impl._M_start); }
^~~~~~~~~~~~~~~~~~~~~~~~
In file included from C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:21:0:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\future:115:11: note: declaration of 'class std::future<std::vector >'
class future;
^~~~~~
In file included from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\vector:64:0,
from C:/MinGW/msys/1.0/home/c4n10/primesieve/include/primesieve/PrimeSieve.hpp:17,
from C:/MinGW/msys/1.0/home/c4n10/primesieve/include/primesieve/ParallelPrimeSieve.hpp:15,
from C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:12:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_vector.h: In instantiation of 'std::vector<_Tp, _Alloc>::size_type std::vector<_Tp, _Alloc>::size() const [with _Tp = std::future<std::vector >; _Alloc = std::allocator<std::future<std::vector > >; std::vector<_Tp, _Alloc>::size_type = unsigned int]':
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\vector.tcc:72:37: required from 'void std::vector<_Tp, _Alloc>::reserve(std::vector<_Tp, _Alloc>::size_type) [with _Tp = std::future<std::vector >; _Alloc = std::allocator<std::future<std::vector > >; std::vector<_Tp, _Alloc>::size_type = unsigned int]'
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:166:28: required from here
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_vector.h:656:50: error: invalid use of incomplete type 'class std::future<std::vector >'
{ return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); }
~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
In file included from C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:21:0:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\future:115:11: note: declaration of 'class std::future<std::vector >'
class future;
^~~~~~
In file included from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\vector:62:0,
from C:/MinGW/msys/1.0/home/c4n10/primesieve/include/primesieve/PrimeSieve.hpp:17,
from C:/MinGW/msys/1.0/home/c4n10/primesieve/include/primesieve/ParallelPrimeSieve.hpp:15,
from C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:12:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_construct.h: In instantiation of 'void std::_Destroy(_ForwardIterator, _ForwardIterator) [with _ForwardIterator = std::future<std::vector >
]':
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_construct.h:151:15: required from 'void std::_Destroy(_ForwardIterator, _ForwardIterator, std::allocator<_T2>&) [with _ForwardIterator = std::future<std::vector >; _Tp = std::future<std::vector >]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_vector.h:426:22: required from 'std::vector<_Tp, _Alloc>::~vector() [with _Tp = std::future<std::vector >; _Alloc = std::allocator<std::future<std::vector > >]'
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:165:30: required from here
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_construct.h:127:11: error: invalid use of incomplete type 'std::iterator_traits<std::future<std::vector >
>::value_type {aka class std::future<std::vector >}'
std::_Destroy_aux<__has_trivial_destructor(_Value_type)>::
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__destroy(__first, __last);

In file included from C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:21:0:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\future:115:11: note: declaration of 'std::iterator_traits<std::future<std::vector<long long unsigned int> >*>::value_type {aka class std::future<std::vector<long long unsigned int> >}'
   class future;
         ^~~~~~
In file included from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\mingw32\bits\c++allocator.h:33:0,
               from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\allocator.h:46,
               from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\vector:61,
               from C:/MinGW/msys/1.0/home/c4n10/primesieve/include/primesieve/PrimeSieve.hpp:17,
               from C:/MinGW/msys/1.0/home/c4n10/primesieve/include/primesieve/ParallelPrimeSieve.hpp:15,
               from C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:12:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\ext\new_allocator.h: In instantiation of '__gnu_cxx::new_allocator<_Tp>::size_type __gnu_cxx::new_allocator<_Tp>::max_size() const [with _Tp = std::future<std::vector<long long unsigned int> >; __gnu_cxx::new_allocator<_Tp>::size_type = unsigned int]':
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\alloc_traits.h:476:29:   required from 'static std::allocator_traits<std::allocator<_Tp1> >::size_type std::allocator_traits<std::allocator<_Tp1> >::max_size(const allocator_type&) [with _Tp = std::future<std::vector<long long unsigned int> >; std::allocator_traits<std::allocator<_Tp1> >::size_type = unsigned int; std::allocator_traits<std::allocator<_Tp1> >::allocator_type = std::allocator<std::future<std::vector<long long unsigned int> > >]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_vector.h:661:39:   required from 'std::vector<_Tp, _Alloc>::size_type std::vector<_Tp, _Alloc>::max_size() const [with _Tp = std::future<std::vector<long long unsigned int> >; _Alloc = std::allocator<std::future<std::vector<long long unsigned int> > >; std::vector<_Tp, _Alloc>::size_type = unsigned int]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\vector.tcc:68:15:   required from 'void std::vector<_Tp, _Alloc>::reserve(std::vector<_Tp, _Alloc>::size_type) [with _Tp = std::future<std::vector<long long unsigned int> >; _Alloc = std::allocator<std::future<std::vector<long long unsigned int> > >; std::vector<_Tp, _Alloc>::size_type = unsigned int]'
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:166:28:   required from here
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\ext\new_allocator.h:114:35: error: invalid application of 'sizeof' to incomplete type 'std::future<std::vector<long long unsigned int> >'
     { return size_t(-1) / sizeof(_Tp); }
                                 ^
In file included from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\vector:63:0,
               from C:/MinGW/msys/1.0/home/c4n10/primesieve/include/primesieve/PrimeSieve.hpp:17,
               from C:/MinGW/msys/1.0/home/c4n10/primesieve/include/primesieve/ParallelPrimeSieve.hpp:15,
               from C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:12:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_uninitialized.h: In instantiation of '_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<std::future<std::vector<long long unsigned int> >*>; _ForwardIterator = std::future<std::vector<long long unsigned int> >*]':
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_uninitialized.h:281:37:   required from '_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::move_iterator<std::future<std::vector<long long unsigned int> >*>; _ForwardIterator = std::future<std::vector<long long unsigned int> >*; _Tp = std::future<std::vector<long long unsigned int> >]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_vector.h:1225:35:   required from 'std::vector<_Tp, _Alloc>::pointer std::vector<_Tp, _Alloc>::_M_allocate_and_copy(std::vector<_Tp, _Alloc>::size_type, _ForwardIterator, _ForwardIterator) [with _ForwardIterator = std::move_iterator<std::future<std::vector<long long unsigned int> >*>; _Tp = std::future<std::vector<long long unsigned int> >; _Alloc = std::allocator<std::future<std::vector<long long unsigned int> > >; std::vector<_Tp, _Alloc>::pointer = std::future<std::vector<long long unsigned int> >*; std::vector<_Tp, _Alloc>::size_type = unsigned int]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\vector.tcc:75:70:   required from 'void std::vector<_Tp, _Alloc>::reserve(std::vector<_Tp, _Alloc>::size_type) [with _Tp = std::future<std::vector<long long unsigned int> >; _Alloc = std::allocator<std::future<std::vector<long long unsigned int> > >; std::vector<_Tp, _Alloc>::size_type = unsigned int]'
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:166:28:   required from here
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_uninitialized.h:124:12: error: invalid use of incomplete type 'std::__iterator_traits<std::move_iterator<std::future<std::vector<long long unsigned int> >*>, void>::value_type {aka class std::future<std::vector<long long unsigned int> >}'
          && __is_trivial(_ValueType2)

In file included from C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:21:0:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\future:115:11: note: declaration of 'std::__iterator_traits<std::move_iterator<std::future<std::vector<long long unsigned int> >*>, void>::value_type {aka class std::future<std::vector<long long unsigned int> >}'
   class future;
         ^~~~~~
In file included from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\vector:63:0,
               from C:/MinGW/msys/1.0/home/c4n10/primesieve/include/primesieve/PrimeSieve.hpp:17,
               from C:/MinGW/msys/1.0/home/c4n10/primesieve/include/primesieve/ParallelPrimeSieve.hpp:15,
               from C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:12:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_uninitialized.h:124:12: error: invalid use of incomplete type 'std::iterator_traits<std::future<std::vector<long long unsigned int> >*>::value_type {aka class std::future<std::vector<long long unsigned int> >}'
          && __is_trivial(_ValueType2)

In file included from C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:21:0:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\future:115:11: note: declaration of 'std::iterator_traits<std::future<std::vector<long long unsigned int> >*>::value_type {aka class std::future<std::vector<long long unsigned int> >}'
   class future;
         ^~~~~~
In file included from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\mingw32\bits\c++allocator.h:33:0,
               from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\allocator.h:46,
               from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\vector:61,
               from C:/MinGW/msys/1.0/home/c4n10/primesieve/include/primesieve/PrimeSieve.hpp:17,
               from C:/MinGW/msys/1.0/home/c4n10/primesieve/include/primesieve/ParallelPrimeSieve.hpp:15,
               from C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:12:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\ext\new_allocator.h: In instantiation of '_Tp* __gnu_cxx::new_allocator<_Tp>::allocate(__gnu_cxx::new_allocator<_Tp>::size_type, const void*) [with _Tp = std::future<std::vector<long long unsigned int> >; __gnu_cxx::new_allocator<_Tp>::pointer = std::future<std::vector<long long unsigned int> >*; __gnu_cxx::new_allocator<_Tp>::size_type = unsigned int]':
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\alloc_traits.h:416:32:   required from 'static _Tp* std::allocator_traits<std::allocator<_Tp1> >::allocate(std::allocator_traits<std::allocator<_Tp1> >::allocator_type&, std::allocator_traits<std::allocator<_Tp1> >::size_type) [with _Tp = std::future<std::vector<long long unsigned int> >; std::allocator_traits<std::allocator<_Tp1> >::pointer = std::future<std::vector<long long unsigned int> >*; std::allocator_traits<std::allocator<_Tp1> >::allocator_type = std::allocator<std::future<std::vector<long long unsigned int> > >; std::allocator_traits<std::allocator<_Tp1> >::size_type = unsigned int]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_vector.h:170:33:   required from 'std::_Vector_base<_Tp, _Alloc>::pointer std::_Vector_base<_Tp, _Alloc>::_M_allocate(std::size_t) [with _Tp = std::future<std::vector<long long unsigned int> >; _Alloc = std::allocator<std::future<std::vector<long long unsigned int> > >; std::_Vector_base<_Tp, _Alloc>::pointer = std::future<std::vector<long long unsigned int> >*; std::size_t = unsigned int]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_vector.h:1222:44:   required from 'std::vector<_Tp, _Alloc>::pointer std::vector<_Tp, _Alloc>::_M_allocate_and_copy(std::vector<_Tp, _Alloc>::size_type, _ForwardIterator, _ForwardIterator) [with _ForwardIterator = std::move_iterator<std::future<std::vector<long long unsigned int> >*>; _Tp = std::future<std::vector<long long unsigned int> >; _Alloc = std::allocator<std::future<std::vector<long long unsigned int> > >; std::vector<_Tp, _Alloc>::pointer = std::future<std::vector<long long unsigned int> >*; std::vector<_Tp, _Alloc>::size_type = unsigned int]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\vector.tcc:75:70:   required from 'void std::vector<_Tp, _Alloc>::reserve(std::vector<_Tp, _Alloc>::size_type) [with _Tp = std::future<std::vector<long long unsigned int> >; _Alloc = std::allocator<std::future<std::vector<long long unsigned int> > >; std::vector<_Tp, _Alloc>::size_type = unsigned int]'
C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:166:28:   required from here
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\ext\new_allocator.h:104:54: error: invalid application of 'sizeof' to incomplete type 'std::future<std::vector<long long unsigned int> >'
return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
                                                    ^
In file included from C:/MinGW/msys/1.0/home/c4n10/primesieve/src/ParallelPrimeSieve.cpp:21:0:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\future: At global scope:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\future:179:5: error: 'std::future<typename std::result_of<typename std::decay<_Tp>::type(typename std::decay<_BoundArgs>::type ...)>::type> std::async(std::launch, _Fn&&, _Args&& ...) [with _Fn = primesieve::ParallelPrimeSieve::sieve()::<lambda()>&; _Args = {}; typename std::result_of<typename std::decay<_Tp>::type(typename std::decay<_BoundArgs>::type ...)>::type = std::vector<long long unsigned int>]', declared using local type 'primesieve::ParallelPrimeSieve::sieve()::<lambda()>', is used but never defined [-fpermissive]
   async(launch __policy, _Fn&& __fn, _Args&&... __args);
   ^~~~~
make[2]: *** [CMakeFiles/libprimesieve-static.dir/src/ParallelPrimeSieve.cpp.obj] Error 1
make[1]: *** [CMakeFiles/libprimesieve-static.dir/all] Error 2
make: *** [all] Error 2




Any help would be greatly appreciated, thanks.

Failed tests with Visual Studio 2015 update 3

If I compile primesieve with VS2015 update 3, it fails tests:

pi(x) : Prime-counting function test
pi(10^1) = 4 OK
pi(10^2) = 25 OK
pi(10^3) = 168 OK
pi(10^4) = 1229 OK
pi(10^5) = 9592 OK
pi(10^6) = 78498 OK
pi(10^7) = 664579 OK
pi(10^8) = 6426034 ERROR

primesieve error: test failed!

Adding "-d2SSAOptimizer-" to compiler's command line fixes the issue, so I see two alternatives here:

  1. There is undefined behavior somewhere in primesieve's code, and the new SSA optimizer in VS2015 update 3 generates different code there (20% chance).
  2. There is a bug in the new SSA optimizer in VS2015 update 3 (80% chance).

Optimizer bug is very likely, but it's still worth investigating for what exactly causes the issue: optimizer bug or undefined behavior.

Conversion from 'const int' to 'primesieve::byte_t', possible loss of data

A user has reported the MSVC warning below when building primesieve in Debug mode (and linking against libprimesieve?!):

C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Tools\MSVC\14.11.25503\include\xutility(2669): warning C4244: '=': conversion from 'const int' to 'primesieve::byte_t', possible loss of data
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Tools\MSVC\14.11.25503\include\xutility(2693): note: see reference to function template instantiation '_OutIt std::_Fill_n_unchecked1<_OutIt,_Diff,_Ty>(_OutIt,_Diff,const _Ty &,std::false_type)' being compiled
        with
        [
            _OutIt=primesieve::byte_t *,
            _Diff=unsigned __int64,
            _Ty=int
        ]
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Tools\MSVC\14.11.25503\include\xutility(2703): note: see reference to function template instantiation '_OutIt std::_Fill_n_unchecked<_Iter,unsigned __int64,_Ty>(_OutIt,_Diff,const _Ty &)' being compiled
        with
        [
            _OutIt=primesieve::byte_t *,
            _Iter=primesieve::byte_t *,
            _Ty=int,
            _Diff=unsigned __int64
        ]
Erat.cpp(202): note: see reference to function template instantiation '_OutIt *std::fill_n<primesieve::byte_t*,uint64_t,int>(_OutIt,_Diff,const _Ty &)' being compiled
        with
        [
            _OutIt=primesieve::byte_t *,
            _Diff=uint64_t,
            _Ty=int
        ]

Vector out of bounds bugs in EratMedium.cpp

I have introduced vector out of bounds bugs in EratMedium.cpp at line 57-58 in primesieve-6.1:

SievingPrime* primes = &primes_[0];
SievingPrime* back = &primes_.back();

The code above causes vector out of bounds bugs if the primes_ vector is empty (not initialized). One cannot access the first/last element of a vector (e.g. primes_[0]) that has not been initialized.

How to fix the bug

Ideally I should get rid of raw SievingPrime* pointers and simply use the primes_ vector. The problem however is that the method EratMedium::crossOff() is important for performance and must run as fast as possible. Currently the inner loop uses lots of local variables (close to 15) and getting rid of raw pointers might increase the number of local variables and therefore there could be a performance regression due to register spilling. So I have to carefully benchmark my code changes.

Thanks to Noah Hufenus for reporting the bug!

Simple is_prime fucntionality in API

Hi it's me again 😅

So this time my suggestion is a simple class that allows to check if a number is a prime number, backed by a primeiterator. I know this is not very hard to implement, but I think it would be a useful thing to have. Maybe even just expose some already existing external code in the API would be enough.

I could also imagine quickly throwing some code together in a PR that would be exactly such a class.

Detect supported but not default C++11 compiler, CMake requirement too strict

GCC 4.8 supports C++11 but it's not on by default, it needs the -std=c++11 flag. CMake properly detects that this GCC supports C++11 but when it tries to build it does not succeed since the -std=c++11 flag is not added on the commandline.

I fixed this in the CMakeList.txt file by adding:

SET( GCC_COMPILE_FLAGS "-std=c++11")
SET( CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} ${GCC_COMPILE_FLAGS}" )

There is probably a more elegant or preferred method to do this with Cmake, but this worked.

Also, the CMakelIst.txt has a cmake_minimum_required(VERSION 3) at the top. This seems too strict, since changing it to VERSION 2.8 worked fine with my default CMake 2.8 install.

Ubuntu 14.04 defaults to CMake 2.8 and GCC 4.8, which is why I hit these two minor hiccups.

🎉

Hi,

I really like you project! Really AWESOME!
Can you tell more about it? When and why you decided to create it? How long it took? What background you have?

I would like to have the primes that it checked to be saved into a text file for personal use.

I would like to have the primes that it checked to be saved into a text file for personal use.
I decompressed the .zip file, but the "cmd" command below does not work. I used the cd command to point to the folder containing the exe, but when i type the command "primesieve.exe 1000 --print > primes.txt" it creates an empty txt file called "primes". There is nothing in it. What i want is a list of primes from 1 to N, but the command only generate an empty file.

Minor performance regression in v7.4

The very recent commit f212a93 which improves caching of small primes unfortunately causes a minor regression in startup performance:

$ ./primesieve 1e19+8e18 -d100
Sieve size = 128 KiB
Threads = 1
100%
Seconds: 3.124
Primes: 0

$ git checkout ..
$ git checkout f212a936f0a66870bb108f77cac4802f3f4dd419
$ make -j8
Scanning dependencies of target libprimesieve-static
[  3%] Building CXX object CMakeFiles/libprimesieve-static.dir/src/IteratorHelper.cpp.o
[  7%] Linking CXX static library libprimesieve.a
[ 80%] Built target libprimesieve-static
Scanning dependencies of target primesieve
[ 84%] Building CXX object CMakeFiles/primesieve.dir/src/console/test.cpp.o
[ 88%] Linking CXX executable primesieve
[100%] Built target primesieve

$ ./primesieve 1e19+8e18 -d100
Sieve size = 128 KiB
Threads = 1
100%
Seconds: 3.446
Primes: 0

ar warning during make

$ make -j8
make  all-am
make[1]: Entering directory '/home/kim/Desktop/primesieve-master'
  CXX      src/primesieve/libprimesieve_la-EratBig.lo
  CXX      src/primesieve/libprimesieve_la-EratMedium.lo
  CXX      src/primesieve/libprimesieve_la-EratSmall.lo
  CXX      src/primesieve/libprimesieve_la-ParallelPrimeSieve.lo
  CXX      src/primesieve/libprimesieve_la-popcount.lo
  CXX      src/primesieve/libprimesieve_la-PrimeFinder.lo
  CXX      src/primesieve/libprimesieve_la-PreSieve.lo
  CXX      src/primesieve/libprimesieve_la-PrimeGenerator.lo
  CXX      src/primesieve/libprimesieve_la-iterator.lo
  CXX      src/primesieve/libprimesieve_la-primesieve_iterator.lo
  CXX      src/primesieve/libprimesieve_la-primesieve_test.lo
  CXX      src/primesieve/libprimesieve_la-PrimeSieve-nthPrime.lo
  CXX      src/primesieve/libprimesieve_la-PrimeSieve.lo
  CXX      src/primesieve/libprimesieve_la-primesieve-api.lo
  CXX      src/primesieve/libprimesieve_la-primesieve-api-c.lo
  CXX      src/primesieve/libprimesieve_la-SieveOfEratosthenes.lo
  CXX      src/primesieve/libprimesieve_la-WheelFactorization.lo
  CXX      src/apps/console/main.o
  CXX      src/apps/console/help.o
  CXX      src/apps/console/cmdoptions.o
  CXXLD    libprimesieve.la
ar: `u' modifier ignored since `D' is the default (see `U')
  CXXLD    primesieve

I have seen this issue on both Ubuntu 15.10 and Fedora 22. According to this post https://bugzilla.redhat.com/show_bug.cgi?id=1155273#c12 it is an automake bug. The bug is very nasty as many libraries which rely on the GNU Build system (a.k.a. Autotools) are affected.

Some projects (e.g. chromium: https://codereview.chromium.org/196583002/diff/20001/build_tools/common.sh) have implemented workarounds e.g. in their configure.ac:

# Silence warning: ar: 'u' modifier ignored since 'D' is the default
AC_SUBST(AR_FLAGS, [cr])

I have searched on the web but so far I have not found an "official" way to fix this issue.

L1_DCACHE_SIZE at execution time

Please determine CACHE sizes at execution time rather than at build time. The rational behind is to provide a computer independent library for distribution.

/usr/bin/ld: cannot find -lprimesieve

I'm on a Linux machine and I followed the official process of installing from the source and exporting LD_LIBARARY_PATH variables in my fish shell.

I tried the example problem of primesieve_iterator.c from the C API given. When I try to compile them with

gcc prog.c -lprimesieve

it says

/usr/bin/ld: cannot find -lprimesieve
collect2: error: ld returned 1 exit status

Am I missing something here or can anyone explain what's going wrong? Thank you.

pkg-config improvement suggestion

I am happy that you have implemented pkg-config already.
However, I still have a suggestion for improvement.
It would be great if libdir=${prefix}/lib/@CMAKE_LIBRARY_ARCHITECTURE@ could actually be libdir=${prefix}/lib64/@CMAKE_LIBRARY_ARCHITECTURE@ or even better have CMAKE decide whether to use lib or lib64.
Thanks a lot!

Prime Sieve - Sporadic Error

The error happens once for about every 5.000 to 10.000 calls to the prime sieve program. For every call I let it sieve a range of 10^11 numbers. If the error happens it counts 1 ... 10 primes too much, hardly ever too less. Very rarely the miscount is larger than 10. If I run the program again on an erroneous range the count is going to be correct, that is the error is sporadic, it cannot be duplicated.
My test frame compares the results with the prime sieve tables of Tomás Oliveira e Silva.
The error probability and the error magnitude is always pretty much the same, regardless of:

  • Compiler (Intel, Borland, Clang, G++ (Cygwin)
  • Compile optimization -o1 or -o2 or -o3
  • Linked to test frame, as DLL or EXE or primesieve.exe itself
  • OpenMP, or ‚manual‘ thread synchronization
  • Number of Threads (4, 6, 8, 10, 12)
  • Processor (Q6600, i7 X980 Black Edition)
  • Overclocked or regular processor speed
  • OS (Vista, W7)
  • Version 5.4 or 5.7 or any other
  • Time between launches 0,1s or 1s or more
  • What range to be sieved
    I’ve sieved so far about 10^17 numbers and still have no clue of what is causing the errors nor why. Of course there are the usual suspects like: Rounding error, Timing problem etc.

Nice! Fast working!

But... CPU calculations only... =(
Also, I cann't see here: https://primesieve.org/downloads/
the option to save prime numbers directly when generation...
If I have generated 10 million primes, this may be pending in the RAM, before writting to the file?
Also, I cann't see the option in console version, to specify the results-file...

I have this code runned on python: https://gist.github.com/bnlucas/5857478
and this working fastly too. Simple cycle with the condition (odd+2)->is_prime?
working on 1 core of CPU, without multithreading,
and I think this can be vectorized to make parallel calculations on GPU!

As I know, "Sieve of Eratosthenes" make excluding not a prime numbers,
and this need to save data in array... If range of primes are big, this not effective...

Miller-Rabin algorithm no need to save any data, and can working with bigIntegers:
https://username1565.github.io/Javascript-Primality-Tester/
Very small algo, but I cann't find portable EXE for windows,
with vectorized implementation of this, for using GPU calculations.

You can be first, who realize this, in your free time - just for fun...
Best regards...

MinGW: error: 'GetLogicalProcessorInformationEx' was not declared in this scope

It seems like I have introduced a MinGW (GCC/Windows) breaking change in CpuInfo.cpp in primesieve-7.3:

+ using LPFN_GLPIEX = decltype(&GetLogicalProcessorInformationEx);
- using LPFN_GLPIEX = BOOL (WINAPI*)(LOGICAL_PROCESSOR_RELATIONSHIP,
-     PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX, PDWORD);
# MSYS2/GCC 8.2.0
$ cmake .. -G "Unix Makefiles"
$ make -j8
...
CpuInfo.cpp:178:33: error: 'GetLogicalProcessorInformationEx' was not declared in this scope

There is a workaround for the bug: We can set _WIN32_WINNT to a number >= 0x601 so that the binary will run on Windows 7 or later (see https://stackoverflow.com/a/15273259/363778).

 cmake .. -G "Unix Makefiles" -DCMAKE_CXX_FLAGS="-D_WIN32_WINNT=0x601"

Big numbers support

Hello,

Is there support for big numbers?

Something like this:

#include <cstdlib>
#include <iostream>
#include <primesieve.hpp>

using namespace std;

int main(int argc, char** argv) {
    
    primesieve::iterator it;
    
    it.skipto(99999999999999999999999999999999999999999);
    
    uint64_t prime = it.next_prime();
    
    std::cout << prime << std::endl;
    
    return 0;
}

Maybe I am missing something....

Salu2

Incorrect number of threads

I have found that for 1e19 primesieve uses an incorrect number of threads.

primesieve 1e19
Sieve size = 256 kilobytes
Threads = -1368480883
0%

windows.h std::max() compiler error

windows.h defines min() & max() as macros. This causes an issue because StorePrimes.hpp uses std::max(...) which causes a compilation error if both windows.h and StorePrimes.hpp (or primesieve.hpp ) are included in the same cpp file:

double x = (double) start;
x = std::max(10.0, x);
include\primesieve\storeprimes.hpp(80): error C2589: '(': illegal token on right side of '::' 

As a workaround I have changed my code to:

double x = (double) start;
x = std::max<double>(10.0, x);

Bindings for other languages

Do you know of bindings for other languages—Python, Ruby and so on? If you do, please could you link them from the readme or faq.

Add an interface for generating primes into a preallocated array instead of vector pushbacks

I'm doing some work generating large sequences of primes. It turned out to be helpful to generate the primes into an array I've allocated ahead of time vs the std::vector interface.

Why? Two reasons:

1) Numpy integeration for python-primesieve wrapper library.

Another reason to do this - I'm using the python bindings to primesieve from https://github.com/hickford/primesieve-python

By adding this array functionality to primesieve, I've got an integration that lets me generate primes inplace into NumPy arrays. This saves lots of copying of large arrays.

2) Scaling.

Turns out the implementation of generating primes does not seem to be scaling well. It seems connected to the user of std::vector to store the resulting data. Generating 10^9 primes is much slower then e.g. 10^8, even when both data sets fit in RAM. You can see some simple performance tests here:

https://gist.github.com/pstoll/ceb08c6b3baad648423c

Implementation

I've already implemented this all. So this issue is pretty much to confirm that you'd be interested in taking the changes back.

@hickford - fyi.

The basic implementation function looks like this:

/// Store the primes within the interval [start, stop]
/// in the array PRIMES of length LEN.
/// @pre stop <= 2^64 - 2^32 * 10.
/// @pre LEN >= n
template <typename T>
inline void generate_n_primes_array(uint64_t n, uint64_t start, T* primes, uint64_t len);
{
  if (primes)
  {
    Array_N_Primes<T> ar(primes, len);
    ar.array_N_Primes(n, start);
  }
}

where ArrayPrimes etc based on Pushback_N_Primes, etc. I'll make a PR but wanted to get your general feedback before doing that.

Thanks, Perry

GCC 8.2.0 (MinGW/MSYS2) -Wcast-function-type warning

$ cmake .. -G"Unix Makefiles" -DBUILD_SHARED_LIBS=OFF -DCMAKE_CXX_FLAGS="-Wall -Wextra" && make -j4                                   -- The CXX compiler identification is GNU 8.2.0
-- Check for working CXX compiler: C:/msys64/mingw64/bin/c++.exe
-- Check for working CXX compiler: C:/msys64/mingw64/bin/c++.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test Wno_fallthrough
-- Performing Test Wno_fallthrough - Success
-- Performing Test atomic64
-- Performing Test atomic64 - Success
-- Found help2man: C:/msys64/usr/bin/help2man
-- Found help2man option: --locale=C.UTF-8
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/kimwa/OneDrive/Documents/GitHub/primesieve/build
Scanning dependencies of target libprimesieve-static
[  4%] Building CXX object CMakeFiles/libprimesieve-static.dir/src/api-c.cpp.obj
[  8%] Building CXX object CMakeFiles/libprimesieve-static.dir/src/api.cpp.obj
[ 12%] Building CXX object CMakeFiles/libprimesieve-static.dir/src/CpuInfo.cpp.obj
[ 16%] Building CXX object CMakeFiles/libprimesieve-static.dir/src/EratBig.cpp.obj
[ 20%] Building CXX object CMakeFiles/libprimesieve-static.dir/src/EratMedium.cpp.obj
[ 24%] Building CXX object CMakeFiles/libprimesieve-static.dir/src/EratSmall.cpp.obj
[ 28%] Building CXX object CMakeFiles/libprimesieve-static.dir/src/iterator-c.cpp.obj
[ 32%] Building CXX object CMakeFiles/libprimesieve-static.dir/src/iterator.cpp.obj

C:/Users/kimwa/OneDrive/Documents/GitHub/primesieve/src/CpuInfo.cpp: In member function 'void primesieve::CpuInfo::init()':
C:/Users/kimwa/OneDrive/Documents/GitHub/primesieve/src/CpuInfo.cpp:182:76: warning: cast between incompatible function types from 'FARPROC' {aka 'long long int (*)()'} to 'LPFN_GLPIEX' {aka 'int (*)(_LOGICAL_PROCESSOR_RELATIONSHIP, _SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*, long unsigned int*)'} [-Wcast-function-type]
       GetModuleHandle(TEXT("kernel32")), "GetLogicalProcessorInformationEx");
# ...

Linking against primesieve.dll fails when using cpuInfo

Building a shared primesieve.dll on Windows works fine with CMake >= 3.4. However the global cpuInfo variable from CpuInfo.hpp is not exported. This is not a big issue since cpuInfo is not part of primesieve's public API.

However the primesieve console application and one of the tests use cpuInfo which causes linker errors when linking against primesieve.dll.

cmdoptions.obj : error LNK2019: unresolved external symbol "class primesieve::CpuInfo const primesieve::cpuInfo" (?cpuInfo@primesieve@@3VCpuInfo@1@B) referenced in function "void __cdecl `anonymous namespace'::optionCpuInfo(void)" (?opt
ionCpuInfo@?A0xfe6d5e28@@YAXXZ) [C:\Users\kimwa\OneDrive\Documents\GitHub\primesieve\build5\primesieve.vcxproj]
C:\Users\kimwa\OneDrive\Documents\GitHub\primesieve\build5\Release\primesieve.exe : fatal error LNK1120: 1 unresolved externals [C:\Users\kimwa\OneDrive\Documents\GitHub\primesieve\build5\primesieve.vcxproj]
Done Building Project "C:\Users\kimwa\OneDrive\Documents\GitHub\primesieve\build5\primesieve.vcxproj" (default targets) -- FAILED.

Done Building Project "C:\Users\kimwa\OneDrive\Documents\GitHub\primesieve\build5\ALL_BUILD.vcxproj" (default targets) -- FAILED.


Build FAILED.

"C:\Users\kimwa\OneDrive\Documents\GitHub\primesieve\build5\ALL_BUILD.vcxproj" (default target) (1) ->
"C:\Users\kimwa\OneDrive\Documents\GitHub\primesieve\build5\primesieve.vcxproj" (default target) (4) ->
(Link target) ->
  cmdoptions.obj : error LNK2019: unresolved external symbol "class primesieve::CpuInfo const primesieve::cpuInfo" (?cpuInfo@primesieve@@3VCpuInfo@1@B) referenced in function "void __cdecl `anonymous namespace'::optionCpuInfo(void)" (?o
ptionCpuInfo@?A0xfe6d5e28@@YAXXZ) [C:\Users\kimwa\OneDrive\Documents\GitHub\primesieve\build5\primesieve.vcxproj]
  C:\Users\kimwa\OneDrive\Documents\GitHub\primesieve\build5\Release\primesieve.exe : fatal error LNK1120: 1 unresolved externals [C:\Users\kimwa\OneDrive\Documents\GitHub\primesieve\build5\primesieve.vcxproj]

    0 Warning(s)
    2 Error(s)

The problem comes from the fact that CMake's -DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=TRUE does not export global variables I think.

MinGW64 doesn't "see" shared library

Hello, sorry to bother you again,

OK, I have a whole new problem now...

I am trying to compile an application which requires primesieve.

I have successfully compiled primesieve, I have the exe, I have primesieve.a and the includes I have placed them into EVERY bin, lib and include folder I could find in my Msys/MinGW64 installation and I am still receiving:

checking for primesieve_init in -lprimesieve... no
configure: error: primesieve library required

When I run ld -lprimesieve --verbose I receive:

GNU ld (GNU Binutils) 2.30
  Supported emulations:
   i386pep
   i386pe
using internal linker script:
==================================================
/* Default linker script, for normal executables */
/* Copyright (C) 2014-2018 Free Software Foundation, Inc.
   Copying and distribution of this script, with or without modification,
   are permitted in any medium without royalty provided the copyright
   notice and this notice are preserved.  */
OUTPUT_FORMAT(pei-x86-64)
SEARCH_DIR("=/mingw64/x86_64-w64-mingw32/lib"); SEARCH_DIR("=/mingw64/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");
SECTIONS
{
  /* Make the virtual address and file offset synced if the alignment is
     lower than the target page size. */
  . = SIZEOF_HEADERS;
  . = ALIGN(__section_alignment__);
  .text  __image_base__ + ( __section_alignment__ < 0x1000 ? . : __section_alignment__ ) :
  {
     KEEP(*(.init))
    *(.text)
    *(SORT(.text$*))
     *(.text.*)
     *(.gnu.linkonce.t.*)
    *(.glue_7t)
    *(.glue_7)
    . = ALIGN(8);
       /* Note: we always define __CTOR_LIST__ and ___CTOR_LIST__ here,
          we do not PROVIDE them.  This is because the ctors.o startup
          code in libgcc defines them as common symbols, with the
          expectation that they will be overridden by the definitions
          here.  If we PROVIDE the symbols then they will not be
          overridden and global constructors will not be run.

          This does mean that it is not possible for a user to define
          their own __CTOR_LIST__ and __DTOR_LIST__ symbols.  If that
          ability is needed a custom linker script will have to be
          used.  (The custom script can just be a copy of this script
          with the PROVIDE() qualifiers added).
          See PR 22762 for more details.  */
       ___CTOR_LIST__ = .;
       __CTOR_LIST__ = .;
       LONG (-1); LONG (-1);
       KEEP (*(.ctors));
       KEEP (*(.ctor));
       KEEP (*(SORT_BY_NAME(.ctors.*)));
       LONG (0); LONG (0);
       /* See comment about __CTOR_LIST__ above.  The same reasoning
          applies here too.  */
       ___DTOR_LIST__ = .;
       __DTOR_LIST__ = .;
       LONG (-1); LONG (-1);
       KEEP (*(.dtors));
       KEEP (*(.dtor));
       KEEP (*(SORT_BY_NAME(.dtors.*)));
       LONG (0); LONG (0);
     KEEP (*(.fini))
    /* ??? Why is .gcc_exc here?  */
     *(.gcc_exc)
    PROVIDE (etext = .);
     KEEP (*(.gcc_except_table))
  }
  /* The Cygwin32 library uses a section to avoid copying certain data
     on fork.  This used to be named ".data".  The linker used
     to include this between __data_start__ and __data_end__, but that
     breaks building the cygwin32 dll.  Instead, we name the section
     ".data_cygwin_nocopy" and explicitly include it after __data_end__. */
  .data BLOCK(__section_alignment__) :
  {
    __data_start__ = . ;
    *(.data)
    *(.data2)
    *(SORT(.data$*))
    KEEP(*(.jcr))
    __data_end__ = . ;
    *(.data_cygwin_nocopy)
  }
  .rdata BLOCK(__section_alignment__) :
  {
    *(.rdata)
             *(SORT(.rdata$*))
    __rt_psrelocs_start = .;
    KEEP(*(.rdata_runtime_pseudo_reloc))
    __rt_psrelocs_end = .;
  }
  __rt_psrelocs_size = __rt_psrelocs_end - __rt_psrelocs_start;
  ___RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
  __RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
  ___RUNTIME_PSEUDO_RELOC_LIST__ = . - __rt_psrelocs_size;
  __RUNTIME_PSEUDO_RELOC_LIST__ = . - __rt_psrelocs_size;
  .eh_frame BLOCK(__section_alignment__) :
  {
    KEEP (*(.eh_frame*))
  }
  .pdata BLOCK(__section_alignment__) :
  {
    KEEP(*(.pdata*))
  }
  .xdata BLOCK(__section_alignment__) :
  {
    KEEP(*(.xdata*))
  }
  .bss BLOCK(__section_alignment__) :
  {
    __bss_start__ = . ;
    *(.bss)
    *(COMMON)
    __bss_end__ = . ;
  }
  .edata BLOCK(__section_alignment__) :
  {
    *(.edata)
  }
  /DISCARD/ :
  {
    *(.debug$S)
    *(.debug$T)
    *(.debug$F)
    *(.drectve)
     *(.note.GNU-stack)
     *(.gnu.lto_*)
  }
  .idata BLOCK(__section_alignment__) :
  {
    /* This cannot currently be handled with grouped sections.
        See pep.em:sort_sections.  */
    KEEP (SORT(*)(.idata$2))
    KEEP (SORT(*)(.idata$3))
    /* These zeroes mark the end of the import list.  */
    LONG (0); LONG (0); LONG (0); LONG (0); LONG (0);
    KEEP (SORT(*)(.idata$4))
    __IAT_start__ = .;
    SORT(*)(.idata$5)
    __IAT_end__ = .;
    KEEP (SORT(*)(.idata$6))
    KEEP (SORT(*)(.idata$7))
  }
  .CRT BLOCK(__section_alignment__) :
  {
    ___crt_xc_start__ = . ;
    KEEP (*(SORT(.CRT$XC*)))  /* C initialization */
    ___crt_xc_end__ = . ;
    ___crt_xi_start__ = . ;
    KEEP (*(SORT(.CRT$XI*)))  /* C++ initialization */
    ___crt_xi_end__ = . ;
    ___crt_xl_start__ = . ;
    KEEP (*(SORT(.CRT$XL*)))  /* TLS callbacks */
    /* ___crt_xl_end__ is defined in the TLS Directory support code */
    ___crt_xp_start__ = . ;
    KEEP (*(SORT(.CRT$XP*)))  /* Pre-termination */
    ___crt_xp_end__ = . ;
    ___crt_xt_start__ = . ;
    KEEP (*(SORT(.CRT$XT*)))  /* Termination */
    ___crt_xt_end__ = . ;
  }
  /* Windows TLS expects .tls$AAA to be at the start and .tls$ZZZ to be
     at the end of the .tls section.  This is important because _tls_start MUST
     be at the beginning of the section to enable SECREL32 relocations with TLS
     data.  */
  .tls BLOCK(__section_alignment__) :
  {
    ___tls_start__ = . ;
    KEEP (*(.tls$AAA))
    KEEP (*(.tls))
    KEEP (*(.tls$))
    KEEP (*(SORT(.tls$*)))
    KEEP (*(.tls$ZZZ))
    ___tls_end__ = . ;
  }
  .endjunk BLOCK(__section_alignment__) :
  {
    /* end is deprecated, don't use it */
    PROVIDE (end = .);
    PROVIDE ( _end = .);
     __end__ = .;
  }
  .rsrc BLOCK(__section_alignment__) : SUBALIGN(4)
  {
    KEEP (*(.rsrc))
    KEEP (*(.rsrc$*))
  }
  .reloc BLOCK(__section_alignment__) :
  {
    *(.reloc)
  }
  .stab BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.stab)
  }
  .stabstr BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.stabstr)
  }
  /* DWARF debug sections.
     Symbols in the DWARF debugging sections are relative to the beginning
     of the section.  Unlike other targets that fake this by putting the
     section VMA at 0, the PE format will not allow it.  */
  /* DWARF 1.1 and DWARF 2.  */
  .debug_aranges BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.debug_aranges)
  }
  .zdebug_aranges BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.zdebug_aranges)
  }
  .debug_pubnames BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.debug_pubnames)
  }
  .zdebug_pubnames BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.zdebug_pubnames)
  }
  .debug_pubtypes BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.debug_pubtypes)
  }
  .zdebug_pubtypes BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.zdebug_pubtypes)
  }
  /* DWARF 2.  */
  .debug_info BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.debug_info .gnu.linkonce.wi.*)
  }
  .zdebug_info BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.zdebug_info .zdebug.gnu.linkonce.wi.*)
  }
  .debug_abbrev BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.debug_abbrev)
  }
  .zdebug_abbrev BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.zdebug_abbrev)
  }
  .debug_line BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.debug_line)
  }
  .zdebug_line BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.zdebug_line)
  }
  .debug_frame BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.debug_frame)
  }
  .zdebug_frame BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.zdebug_frame)
  }
  .debug_str BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.debug_str)
  }
  .zdebug_str BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.zdebug_str)
  }
  .debug_loc BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.debug_loc)
  }
  .zdebug_loc BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.zdebug_loc)
  }
  .debug_macinfo BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.debug_macinfo)
  }
  .zdebug_macinfo BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.zdebug_macinfo)
  }
  /* SGI/MIPS DWARF 2 extensions.  */
  .debug_weaknames BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.debug_weaknames)
  }
  .zdebug_weaknames BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.zdebug_weaknames)
  }
  .debug_funcnames BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.debug_funcnames)
  }
  .zdebug_funcnames BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.zdebug_funcnames)
  }
  .debug_typenames BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.debug_typenames)
  }
  .zdebug_typenames BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.zdebug_typenames)
  }
  .debug_varnames BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.debug_varnames)
  }
  .zdebug_varnames BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.zdebug_varnames)
  }
  .debug_macro BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.debug_macro)
  }
  .zdebug_macro BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.zdebug_macro)
  }
  /* DWARF 3.  */
  .debug_ranges BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.debug_ranges)
  }
  .zdebug_ranges BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.zdebug_ranges)
  }
  /* DWARF 4.  */
  .debug_types BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.debug_types .gnu.linkonce.wt.*)
  }
  .zdebug_types BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.zdebug_types .zdebug.gnu.linkonce.wt.*)
  }
  /* For Go and Rust.  */
  .debug_gdb_scripts BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.debug_gdb_scripts)
  }
  .zdebug_gdb_scripts BLOCK(__section_alignment__) (NOLOAD) :
  {
    *(.zdebug_gdb_scripts)
  }
}


==================================================
attempt to open c:\msys64\mingw64\bin\../../mingw64/mingw64/x86_64-w64-mingw32/lib/libprimesieve.dll.a failed
attempt to open c:\msys64\mingw64\bin\../../mingw64/mingw64/x86_64-w64-mingw32/lib/primesieve.dll.a failed
attempt to open c:\msys64\mingw64\bin\../../mingw64/mingw64/x86_64-w64-mingw32/lib/libprimesieve.a failed
attempt to open c:\msys64\mingw64\bin\../../mingw64/mingw64/x86_64-w64-mingw32/lib/primesieve.lib failed
attempt to open c:\msys64\mingw64\bin\../../mingw64/mingw64/x86_64-w64-mingw32/lib/libprimesieve.dll failed
attempt to open c:\msys64\mingw64\bin\../../mingw64/mingw64/x86_64-w64-mingw32/lib/primesieve.dll failed
attempt to open c:\msys64\mingw64\bin\../../mingw64/mingw64/x86_64-w64-mingw32/lib\libprimesieve.a failed
attempt to open c:\msys64\mingw64\bin\../../mingw64/mingw64/lib/libprimesieve.dll.a failed
attempt to open c:\msys64\mingw64\bin\../../mingw64/mingw64/lib/primesieve.dll.a failed
attempt to open c:\msys64\mingw64\bin\../../mingw64/mingw64/lib/libprimesieve.a failed
attempt to open c:\msys64\mingw64\bin\../../mingw64/mingw64/lib/primesieve.lib failed
attempt to open c:\msys64\mingw64\bin\../../mingw64/mingw64/lib/libprimesieve.dll failed
attempt to open c:\msys64\mingw64\bin\../../mingw64/mingw64/lib/primesieve.dll failed
attempt to open c:\msys64\mingw64\bin\../../mingw64/mingw64/lib\libprimesieve.a failed
attempt to open c:\msys64\mingw64\bin\../../mingw64/usr/local/lib/libprimesieve.dll.a failed
attempt to open c:\msys64\mingw64\bin\../../mingw64/usr/local/lib/primesieve.dll.a failed
attempt to open c:\msys64\mingw64\bin\../../mingw64/usr/local/lib/libprimesieve.a failed
attempt to open c:\msys64\mingw64\bin\../../mingw64/usr/local/lib/primesieve.lib failed
attempt to open c:\msys64\mingw64\bin\../../mingw64/usr/local/lib/libprimesieve.dll failed
attempt to open c:\msys64\mingw64\bin\../../mingw64/usr/local/lib/primesieve.dll failed
attempt to open c:\msys64\mingw64\bin\../../mingw64/usr/local/lib\libprimesieve.a failed
attempt to open c:\msys64\mingw64\bin\../../mingw64/lib/libprimesieve.dll.a failed
attempt to open c:\msys64\mingw64\bin\../../mingw64/lib/primesieve.dll.a failed
attempt to open c:\msys64\mingw64\bin\../../mingw64/lib/libprimesieve.a succeeded

As you can see, for some reason it only sees the one libprimesieve.a file.

I have even tried pointing the compiler to the compiled files in my primesieve folder directly by using:

$ export CPPFLAGS='-I../primesieve/include/'
$ export LDFLAGS='-L../primesieve/build/'

Still with the same results.

Any help you can offer would be greatly appreciated once again...

Use Meyer's singleton for cpuInfo

Currently cpuInfo is defined as a global singleton in CpuInfo.cpp. Hence the cpuInfo object is initialised as soon as libprimesieve is loaded, even if it is not needed. This cloud be a minor issue when using libprimesieve because loading libprimesieve will always result in a minor delay due to initialising cpuInfo.

Hence I suggest to convert the cpuInfo singleton into a Meyer's singleton that is only initialised once cpuInfo is used the first time. The C++11 Meyer's singleton is thread-safe which is exactly what we need.

CPU cache detection issues on Windows

Currently I am using the following code on Windows to get the number of logical CPU cores (threads) in CpuInfo.cpp:

if (!glpi(&info[0], &bytes))
  return;

for (size_t i = 0; i < size; i++)
{
  if (info[i].Relationship == RelationProcessorCore)
  {
    auto mask = info[i].ProcessorMask;

    // ProcessorMask contains one bit set for
    // each logical CPU core related to the
    // current physical CPU core
    for (threadsPerCore = 0; mask > 0; threadsPerCore++)
    mask &= mask - 1;

    std::cout << "threadsPerCore = " << threadsPerCore << std::endl;
  }

The problem is that this works correctly on some systems but not on all systems. Windows may in fact assign the different logical CPU cores of one physical CPU to different processor relationships. On my Windows PC with an Intel Core i7-6700 CPU with 8 threads the output is as follows:

threadsPerCore = 2
threadsPerCore = 2
threadsPerCore = 2
threadsPerCore = 2

Hence Windows has created 4 processor groups with each 2 logical CPU cores. This means that my code above cannot be used reliably to get the total number of CPU threads. We could theoretically simply sum the threads 2+2+2+2 = 8 but I am unsure whether this is reliable...

Windows is currently a big mess compared to Linux and macOS for getting CPU cache size information. My current code for retrieving the number of logical CPU cores sharing the L2 cache does not work correctly on VMs:

// check L2 cache
if (cpu->Relationship == RelationCache &&
    cpu->Cache.GroupMask.Group == 0 &&
    cpu->Cache.Level == 2 &&
    (cpu->Cache.Type == CacheData ||
     cpu->Cache.Type == CacheUnified))
{
  // @warning: GetLogicalProcessorInformationEx() reports
  // incorrect data when Windows is run inside a virtual
  // machine. Specifically the GROUP_AFFINITY.Mask will
  // only have 1 or 2 bits set for each CPU cache (L1, L2 and
  // L3) even if more logical CPU cores share the cache
  auto mask = cpu->Cache.GroupMask.Mask;
  size_t threads = 0;

  // Cache.GroupMask.Mask contains one bit set for
  // each logical CPU core sharing the cache
  for (; mask > 0; threads++)
    mask &= mask - 1;

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.