1至1000万范围内盈数计数GPU运行耗时优化方案求助
1~1000万区间盈数计数GPU优化建议
约束条件:不得使用数学库依赖函数,不得使用动态/静态数据结构,目标GPU运行耗时≤10秒
现有代码核心问题
现有实现存在两个核心问题:一是质因数分解逻辑错误,if(1>temp)判断永远不成立,会漏掉剩余质因数的约数和计算,且product乘积时机错误,导致约数和计算完全不符合要求;二是逐数串行计算的O(N√N)复杂度未适配GPU并行架构,是耗时过高的核心原因。
可行优化方案
- 先修正基础逻辑错误:调整剩余质因数判断条件为
temp>1,将每个质因数的sum计算完成后再乘入product,确保约数和计算结果正确。修正后的基础逻辑参考:
#include<stdio.h> #define MAXNUM 10000000 int main(void){ int counta=0; for(unsigned n=1;n<=MAXNUM;++n){ unsigned temp=n; unsigned product=1; // 单独处理质因数2 if(temp % 2 == 0) { unsigned sum=1; while(temp %2 ==0) { sum = 1 + sum *2; temp /=2; } product *= sum; } // 处理所有奇质因数 for(unsigned p=3;p*p<=temp;p+=2){ unsigned sum=1; while(temp % p==0){ sum = 1 + sum *p; temp /=p; } product *= sum; } // 处理剩余的大质因数 if(temp>1) { product *= 1 + temp; } if(product>2*n) counta++; } printf("Numbers abundant: %d\n",counta); return 0; }
- 并行化改造适配GPU:将1~1000万的数值区间拆分为数千个等大小的子区间,每个GPU线程独立负责一个子区间内的盈数计数,线程间无任何依赖、不需要额外数据共享、不需要同步操作,完全满足不使用额外数据结构的约束,GPU多核利用率可以提升数十倍。
- 压缩计算范围:盈数中模6余1、5的数占比极低,可先跳过这部分数统计,最后单独计算其中极少的盈数,整体计算量直接降低1/3。
- 优化质因数遍历步长:将奇质因数遍历步长从2调整为6,仅判断p和p+2是否为因数,循环次数直接降低到原来的1/3,单线程执行效率提升2倍以上。
- 循环展开优化:每个线程内的质因数分解循环做手动展开,减少分支判断开销,编译器开启最高等级优化,进一步提升单线程执行效率。
经过上述优化后,1000万规模的盈数计数在普通消费级GPU上运行耗时可以控制在10秒以内。
内容的提问来源于stack exchange,提问作者Beasty
相关产品推荐
相关产品推荐

