C_and_CPP 板


LINE

开发平台(Platform): (Ex: Win10, Linux, ...) Linux上安装CUDA环境 (CUDA版本为8.0 运算能力为3.7)(Tesla K80) 编译器(Ex: GCC, clang, VC++...)+目标环境(跟开发平台不同的话需列出) NVCC 额外使用到的函数库(Library Used): (Ex: OpenGL, ...) 问题(Question): 研究上要作大整数乘法,我找到一个可以成功执行的程式,只不过这个程式是用C++写的 ,并且其中的fft是使用复数的方式来做计算。我想把它改成CUDA C版本,并且其中的fft 是用整数来做运算,请问这样是可行的吗?程式我自己有先看过了,大概了解每一个func tion的动作,但是其中还有一些小细节看不太懂(不懂的地方我有注解),请各位大大帮 我看看,谢谢。 喂入的资料(Input): 预期的正确结果(Expected Output): 错误结果(Wrong Output): 程式码(Code):(请善用置底文网页, 记得排版) #include <iostream> #include <cmath> #include <complex> #include <cstring> using namespace std; const double PI = acos(-1.0); typedef complex<double> cp; typedef long long int64; const int N = 1 << 16; int64 a[N], b[N], c[N << 1]; void bit_reverse_copy(cp a[], int n, cp b[]) { int i, j, k, u, m; for (u = 1, m = 0; u < n; u <<= 1, ++m); for (i = 0; i < n; ++i) { j = i; k = 0; for (u = 0; u < m; ++u, j >>= 1) k = (k << 1) | (j & 1); b[k] = a[i]; } } void FFT(cp _x[], int n, bool flag) // bool flag怎麽改成c版本参数? { static cp x[N << 1]; bit_reverse_copy(_x, n, x); int i, j, k, kk, p, m; for (i = 1, m = 0; i < n; i <<= 1, ++m); double alpha = 2 * PI; if (flag) alpha = -alpha; //这行是什麽意思? for (i = 0, k = 2; i < m; ++i, k <<= 1) { cp wn = cp(cos(alpha / k), sin(alpha / k)); for (j = 0; j < n; j += k) { cp w = 1, u, t; kk = k >> 1; for (p = 0; p < kk; ++p) { t = w * x[j + p + kk]; u = x[j + p]; x[j + p] = u + t; x[j + p + kk] = u - t; w *= wn; } } } memcpy(_x, x, sizeof(cp) * n); } void polynomial_multiply(int64 a[], int na, int64 b[], int nb, int64 c[], int &nc) { int i, n; i = max(na, nb) << 1; for (n = 1; n < i; n <<= 1); static cp x[N << 1], y[N << 1]; for (i = 0; i < na; ++i) x[i] = a[i]; for (; i < n; ++i) x[i] = 0; FFT(x, n, 0); for (i = 0; i < nb; ++i) y[i] = b[i]; for (; i < n; ++i) y[i] = 0; FFT(y, n, 0); for (i = 0; i < n; ++i) x[i] *= y[i]; FFT(x, n, 1); for (i = 0; i < n; ++i) { c[i] = (int64)(x[i].real() / n + 0.5); } for (nc = na + nb - 1; nc > 1 && !c[nc - 1]; --nc); } const int LEN = 5, MOD = 100000; void convert(char *s, int64 a[], int &n) { int len = strlen(s), i, j, k; for (n = 0, i = len - LEN; i >= 0; i -= LEN) { for (j = k = 0; j < LEN; ++j) k = k * 10 + (s[i + j] - '0'); a[n++] = k; } i += LEN; if (i) { for (j = k = 0; j < i; ++j) k = k * 10 + (s[j] - '0'); a[n++] = k; } } void print(int64 a[], int n) { printf("%I64d", a[--n]); while (n) printf("%05I64d", a[--n]); puts(""); } char buf[N + 10]; int main() { int na, nb, nc; while (scanf("%s", buf) != EOF) { bool sign = false; //这行是什麽意思? if (buf[0] == '-') { sign = !sign; // 这行是什麽意思? convert(buf + 1, a, na); } else convert(buf, a, na); scanf("%s", buf); if (buf[0] == '-') { sign = !sign; convert(buf + 1, b, nb); } else convert(buf, b, nb); polynomial_multiply(a, na, b, nb, c, nc); int64 t1, t2; t1 = 0; for (int i = 0; i < nc; ++i) { t2 = t1 + c[i]; c[i] = t2 % MOD; t1 = t2 / MOD; } for (; t1; t1 /= MOD) c[nc++] = t1 % MOD; if (sign) putchar('-'); print(c, nc); } return 0; } 补充说明(Supplement): 大整数乘法中有一个mod p(质数)的运算,论文上选择的p=0xFFFFFFFF00000001,我该 怎麽在程式中定义一个这麽大的变数呢?如果我只要让GPU作fft运算,是否只要将fft那 个function改写成cuda函式就可以了呢? --



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 140.136.45.205
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1483435022.A.D71.html
1F:推 nick5130: sign是为了处理负数01/03 18:3
2F:推 nick5130: flag也是为了处理负数01/03 18:45
3F:→ nick5130: c没有bool你用int 0跟1就可以处理了01/03 18:45
4F:→ nick5130: 然後我不懂你是为了什麽要用CUDA01/03 18:46
5F:→ nick5130: 如果你是为了加速运算,这种程度的运算改成CUDA只会变慢01/03 18:47
6F:→ nick5130: 如果你是为了交差就当我没说就好01/03 18:47
谢谢nick大,会使用CUDA是为了实现论文上的大整数数乘法(65536点的FFT,大整数可达2 的786432次方),是为了加速运算没错。想用这个程式去改的原因是,作者有注明可以支 援到30万位元整数乘法,这个运算量对GPU来说,应该也不算小才是阿,为什麽会变慢呢 ? 谢谢p大,不过这个fft程式似乎也是使用复数的方式做运算,不是用整数的方式。
8F:→ Sylveon: 不想小数运算可以用数论变换ntt来做,可是大量的取模以01/03 19:51
9F:→ Sylveon: 防及溢位的细结放一起後,实测上没fft快01/03 19:51
10F:推 lc85301: 我记得没错的话fft 要到1000 bit 以上才有竞争力01/04 11:38
※ 编辑: tmbyksdG (59.115.156.82), 01/05/2017 00:55:46 ※ 编辑: tmbyksdG (59.115.156.82), 01/05/2017 01:01:23
11F:推 nick5130: CUDA可能比较慢的原因是在PCIE的频宽01/05 09:21
12F:→ nick5130: 加上个人认为你对C不太熟01/05 09:23
13F:→ nick5130: 如果这只是你其中一部分研究 可以考虑改multi thread就01/05 09:23
14F:→ nick5130: 好01/05 09:23
15F:→ nick5130: 如果真的还是觉得慢再评估要不要改成CUDA 01/05 09:24
16F:→ nick5130: 一样project改成multi thread跟cuda所需时间绝对不同 01/05 09:25
17F:→ nick5130: 也不是说改成CUDA就一定会比multi thread快的 01/05 09:25
18F:→ nick5130: 其他比较慢的原因就是演算法的问题了 这边你可以翻看看 01/05 09:31
19F:→ nick5130: 一般cuda的tutorial看看再和你这个比比看 01/05 09:31
20F:→ nick5130: 简单说就是平行化的问题 大概就这样 01/05 09:32
之前学完C之後,的确有一段时间没有继续碰它,这学期修资料结构,才又开始恶补这样 。我想请教nick大,如何在具有C的基本知识条件下,进一步去加强写C的能力。平行化相 关的知识有没有推荐的书籍?我的研究必须用CUDA来实现来实现,利用其他途径目前是不 考虑的。
21F:→ pttworld: 实数、虚数计算和整数定义不一样,感觉难以达成。 01/05 10:50
22F:→ a1u1usul3: 楼主好像对C/CPP也不熟,对平行化也不熟 01/05 12:37
是的,我的确没学过CPP。我想请教a大,如何在具有C的基本知识条件下,进一步去加强 写C的能力。平行化相关的知识有没有推荐的书籍?
23F:→ a1u1usul3: 先用openmp加速,熟悉这个程式,想好相依性和可平行化 01/05 12:38
24F:→ a1u1usul3: 的部分,再改cuda吧。 01/05 12:38
25F:推 friends29: 是可以用cuda啦 只是你的写法不好的话 效率不会比较好01/06 20:57
※ 编辑: tmbyksdG (114.136.66.135), 01/09/2017 12:55:00
26F:→ sunneo: 你乾脆用cufft ... 02/02 21:30







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:WOW站内搜寻

TOP