liangbch 发表于 2008-3-18 14:45:29

在siftPrime.h 中定义L2_CACHE,如果你的电脑L2_CACHE 不是512K,请试着修改为实际值。

shines 发表于 2008-3-18 19:02:44

to liangbch:
由于我们的代码实际上都没有输出素数,tprime的也一样,所以我修改了一下你的代码,否则没有可比性
统计素数的个数而不输出素数表,而我的代码里有2种方式,一种是仅筛法和统计每分段的素数,另一种是保留所有的bit位数组,且统计所有素数个数,程序最后可以检验0-N任何一个数是否为素数,不过计算2-2^30两者相差仅0.2秒而已。

你的代码比我的稍快,不过最快的应该还是GxQcn的。

改进后,仅统计个数
sift prime from 2 to n
n=?(n=0 will exit)1073741824
Total 54400028 in 1073741824
It take 1656 ms
sift prime from 2 to n
n=?(n=0 will exit)2147483648
Total 105097565 in 2147483648
It take 3500 msunsigned char bitcount_index_table[] =
{
        8, 7, 7, 6, 7, 6, 6, 5, 7, 6, 6, 5, 6, 5, 5, 4,
        7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3,
        7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3,
        6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2,
        7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3,
        6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2,
        6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2,
        5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1,
        7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3,
        6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2,
        6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2,
        5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1,
        6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2,
        5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1,
        5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1,
        4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0
};

// 由于统计个数和你的是反的,要处理一下
for (i=0;i<256;i++)
    bitcount_index_table = 8 - bitcount_index_table;

static UINT64 GetPrimeFromSiftBuff2(const BYTE *siftBuff,UINT64 begin, UINT64 end,
                                           UINT64 currCount, int mode)
{
        assert(begin % 30==0);
        DWORD endIdx;
               
        DWORD i,j;
        UINT64 pr=currCount;
        const BYTE maskArray[]={1,2,4,8,16,32,64,128};
        const BYTE remArray[]={1,7,11,13,17,19,23,29};

        endIdx=(DWORD)((end-begin)/30-1);
        if (mode==4)
        {
                for (i=0;i<=endIdx;i++)
                {
                        BYTE keyBYTE;
                        keyBYTE = siftBuff;
                        pr += bitcount_index_table;
                }

                i=endIdx+1;
                for (j=0;j<8;j++)
                {
                        DWORD tmp=MUL30(i)+(DWORD)begin + remArray;
                        if (tmp>end)
                                break;
                        if( siftBuff & maskArray )
                        {
                                pr++;
                        }
                }
        }
        else if (mode==8)
        {
                for (i=0;i<=endIdx;i++)
                {
                        BYTE keyBYTE;
                        keyBYTE = siftBuff;
                        pr += bitcount_index_table;
                }

                i=endIdx+1;
                for (j=0;j<8;j++)
                {
                        UINT64 tmp=(UINT64)i *30I64+ begin + (UINT64)remArray;
                        if (tmp>end)
                                break;
                        if( siftBuff & maskArray )
                        {
                                pr++;
                        }
                }
        }
        return pr;
}

tprime 发表于 2008-3-19 09:48:34

GxQcn没有公开算法, 所以谁也不知道其中的奥妙所在

无心人 发表于 2008-3-19 10:00:32

他程序计时存在问题
如果是筛法时间不应该这么少
1亿最小时间大于0.01s

tprime 发表于 2008-3-19 10:07:39

10亿应该不小于500 ms,这是我见过的最快筛法
代码过于复杂没看懂

无心人 发表于 2008-3-19 10:35:31

等俺封存了128乘再和你们混筛法
现在发问题速度太快了

:)
指不定哪天欠账太多被讨债

tprime 发表于 2008-3-19 10:36:33

你到处开辟战场能不累吗

无心人 发表于 2008-3-19 10:54:22

怕什么时候就忘记了
好多东西是一时兴起想起来的

反正这么多人觉得有意思就好了

liangbch 发表于 2008-3-19 11:29:25

原帖由 无心人 于 2008-3-19 10:00 发表 http://images.5d6d.net/dz60/common/back.gif
他程序计时存在问题
如果是筛法时间不应该这么少
1亿最小时间大于0.01s
同感,我也觉得他的计时存在问题,如果是筛法时间不应该这么少。

shines 发表于 2008-3-19 20:57:07

他计算素数个数应该是用的PI(X)函数,筛法是不可能的,反正只是统计,不比用筛法,这点分得很仔细,不过第一次用会吓一跳
页: 1 2 3 [4] 5 6 7 8 9 10 11 12
查看完整版本: 10秒内计算出1亿素数表, 不输出