5

我用 C++ 编写了一个素数筛程序,它使用 ~12GB 内存来计算低于 100,000,000,000(1000 亿)的所有素数。

该程序在使用 Visual Studio 2012(在为 x64 设置的项目中)以及 64 位 linux 上的 g++ 编译时运行良好。但是,当在 Windows 7 Home Premium 64 位的 cygwin64 中使用 g++ 编译时,尝试使用超过 ~2GB 的内存时会发生分段错误(运行筛子 > ~17,000,000,000)

我相当确定它作为 64 位进程运行,因为任务管理器中的进程名称旁边没有 *32。

编码:

#include <iostream>
#include <vector>
#include <cmath>
#include <cstdlib>
using namespace std;

long long sieve(long long n);

int main(int argc, char** argv) {
    const long long ONE_BILLION = 1000*1000*1000;
    if(argc == 2)
        cout << sieve(atol(argv[1])) << endl;
    else
        cout << sieve(ONE_BILLION * 100) << endl;
}

long long sieve(long long n) {
    vector<bool> bools(n+1);
    for(long long i = 0; i <=n; i++) 
        bools[i] = true;

    double csqrtn = sqrt(n);
    for (long long i = 2; i < csqrtn; ++i)
        if (bools[i]) 
            for (long long j = i * i; j < n; j += i) 
                bools[j] = false;

    long long primes2 = 0;
    for (long long i = 2; i < n; i++) 
        if (bools[i]) 
            primes2++;

    return primes2;
}

在 Visual Studio 中工作正常:

在此处输入图像描述

在 x64 linux 上工作正常:

在此处输入图像描述

使用命令编译:

$ g++ -O3 sieve.cpp -o sieve.exe

跑180亿失败:

$ ./sieve.exe 18000000000
Segmentation fault (core dumped)

工作正常(根据任务管理器使用 2,079,968 K 内存,尽管我的声誉不允许我发布第三个链接。)

$ ./sieve.exe 17000000000
755305935

g++ 版本:

$ g++ --version
g++ (GCC) 4.8.1
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

注意:如果您打算自己尝试运行它,可能需要很长时间。在 3570k @ 4.2GHz 上,在 Visual Studio 中运行 1000 亿次需要大约 30 分钟,10 亿次大约需要 10 秒。但是,您也许可以仅使用向量分配来复制错误。

编辑:因为我没有明确提出问题:为什么会发生这种情况?它是 cygwin64 dll 的限制吗(cygwin64 大约一个月前才完全发布)?

4

1 回答 1

0

尝试增加 cygwin 内存限制。此cygwin 文档建议 64 位平台上的默认最大应用程序堆大小为 4GB...虽然,这可能是指 64 位平台上的 32 位可执行文件...不确定 cygwin64 64 位应用程序会受到哪些限制有关于他们的最大堆大小。

于 2013-08-18T02:06:50.030 回答