Tag: 优化

使用c进行OpenMP优化

我应该优化下面的代码,使其使用openMP和内存阻塞运行至少16倍。 到目前为止,我只能想到使用下面的简单语句来折叠for循环。 这使它运行速度提高了3倍。 有什么想让它接近16? int i,j; #pragma omp parallel for collapse(2) //my inserted code for (i = 0; i < MSIZE; i++) for (j = 0; j < MSIZE; j++) d[i][j] = c[j][i];

骑士的巡回算法

所以我必须编写这个算法(这个版本不需要在骑士开始的同一个地方结束),我让它工作,但它太慢了。 对于size = 8,它适用于起始位置x = 0和y = 0,但是如果我尝试将x和y操纵为例如2和4,则它在几分钟后不会结束。 有人可以帮忙吗? #include #define size 8 int ruch_x[]={ -1, 1, -2, 2, -2, 2, -1, 1}; //arrays of possible knight moves, for example 2nd move is [1,2]// int ruch_y[]={ 2, 2, 1, 1, -1, -1, -2, -2}; int done(int szach[][size]) { for(int i=0;i<size;i++) { for(int j=0;j<size;j++) { if(szach[i][j]==0) […]

将2D数组转换为char *数组并将char复制到字符串结尾的最快方法

我正在寻找一个示例代码或如何改进下面的代码(它是非常慢的IMO,但我可以写),以最快的方式将2D数组转换为char*并将char复制到它。 char* join(int c, size_t arrsize, const char* arr[]) { char *buf, *tbuf, *val; size_t i, vsize, total; buf = malloc(1); for(i = total = 0; i < arrsize; ++i) { val = arr[i]; vsize = strlen(val); if((tbuf = realloc(buf, total + vsize + 2)) == NULL) { if(buf != NULL) free(buf); return NULL; } […]

C中更快IO的其他选择是什么?

我实现了合并排序,并将其用作此codechef问题的解决方案。 这是提交的内容 。 代码放在下面。 我认为导致执行缓慢的问题是我的IO在main函数中很慢。 我知道输入的元素数量,因此必须有一些更快的方式来读取输入而不是我正在做的方式。 是否有更快的IO方法而不是我在main函数中使用的方法? 我听说过使用buffer, fgets和sscanf但我不知道它们是否更快。 任何代码示例都会有所帮助。 #include #include void merge_parts(int arr[], int length) { int *ans; int i, j, k; int temp = length/2; ans = malloc(sizeof(int) * length); //This while and next if-else puts the merged array into temporary array ans for (j = temp, i = k = 0; […]

在C语言中进行类型转换后复制数组的方法更快?

我有一个二维整数数组InArray[2][60]携带2个LS字节的short数据和2个MS字节的位字段数据。 请建议一个更快的方法来提取short数据并将其复制到一个short OutArray[60] ,这是memcpy()的行。 我认为迭代每个项目不是最佳的方法。 TIA 编辑:添加代码段 int InArray[2][60]; short OutArray[60]; for (int i=0; i < 60;i++) { OutArray[i] = (short)(InArray[0][i] & 0xffff); } 有没有更好,更快的方法来做到这一点

如何让我的GPU上的IDCT运行得更快?

我正在尝试从GPU的代码中优化IDCT。 我在NVIDIA Tesla k20c系统上使用的GPU。 原始代码中编写的IDCT函数如下所示: void IDCT(int32_t *input, uint8_t *output) { int32_t Y[64]; int32_t k, l; for (k = 0; k < 8; k++) { for (l = 0; l < 8; l++) Y(k, l) = SCALE(input[(k << 3) + l], S_BITS); idct_1d(&Y(k, 0)); } for (l = 0; l < 8; l++) { int32_t […]

除-Ofast以外的任何内容都会导致“未定义的引用”错误

我有一个包含math.h的C程序,并使用该头文件中的sqrt函数。 非常奇怪的是,当我没有传递-Ofast标志时,我的代码无法编译。 如果我使用以下代码编译我的代码: gcc -std=c99 foo.c 要么本身,要么添加任何-O1 , -O2或-Os (那些是大写的O)到该命令,我得到以下错误: /tmp/ccAcT2Bz.o: In function `sum_of_divisors’: foo.c:(.text+0xb): undefined reference to `sqrt’ collect2: error: ld returned 1 exit status -O3给出了一个类似但更精细的错误(请注意,我不在main调用sqrt ): /tmp/ccBKvvFS.o: In function `sum_of_divisors’: foo.c:(.text+0x5c): undefined reference to `sqrt’ /tmp/ccBKvvFS.o: In function `main’: foo.c:(.text.startup+0xe5): undefined reference to `sqrt’ foo.c:(.text.startup+0xf3): undefined reference to `sqrt’ collect2: error: ld returned […]

如何有效地引用计数cons细胞(检测周期)?

我需要制作一些liblisp (在C11中),它需要处理基本函数,就像libobjc为Objective-C语言libobjc那样。 编辑 我正在将问题重写为不太通用的问题。 我得到了这样的实现: typedef struct cons { void *car, *cdr; } *cons_t; cons_t cons_init(void *, void *); void *cons_get_car(cons_t); void *cons_get_cdr(cons_t); void cons_set_car(cons_t, void *); void cons_set_cdr(cons_t, void *); void cons_free(cons_t); bool cons_is_managed(cons_t); 所以我可以制作一个cons单元格(它使用带引用计数对象的内存池)。 我还可以使用cons_is_managed来检查cons单元是否在内存池中(因此您可以使用外部定义的单元格,而不是使用cons_init创建的单元格(如静态数据))。 我怎么能在这里有效地实现自动引用计数,如果有人调用cons_set_car或cons_set_cdr ,如果void *参数是一个被管理的cons单元,它会增加引用计数? 后宫和乌龟的问题在这里没有用,因为每个单元都有两种可能的方法(如果汽车或cdr是conses它可能无处可去),它们可以是列表,树或图形。 我应该注册cons_set_car / cons_set_cdr中使用的外部(非托管)conses,以便找到涉及它们的循环,但我仍然不确定如何有效地执行此操作。 由于这是一个更受控制的上下文,然后是图形中的一般循环(节点上最多两个顶点),我是否有机会在线性时间内完成此操作并避免垃圾收集(这将是我的计划B)? 主要问题是这是任何函数式语言的核心,所以这些函数会被调用很多次(比如obj_msgSend ),它们是瓶颈。 谢谢。 在另一种方法上,简化问题:如何在基于引用计数的语言上实现cons单元格,如Objective-C + ARC或Vala?

高效的手动循环展开

我有这个C代码: for (k = 0; k < n_n; k++) { if (k == i || k == j) continue; dd=q2_vect[k]-q1_vect; d2=dd*dd; if (d2<0) { a=1; break; } } 出于编译器优化的原因(在Cell处理器的SPE上),我需要手动解开这个,所以我尝试了: dd=q2_vect[0]-q1_vect; d2=dd*dd; if (d2<0)goto done; dd=q2_vect[1]-q1_vect; d2=dd*dd; if (d2<0)goto done; dd=q2_vect[2]-q1_vect; d2=dd*dd; if (d2<0)goto done; ….. ….. // end goto notdone; done: ok=0; notdone: ….. 但我不知道如何应对 […]

在计算中预先定义常用值 – 它会改变什么吗?

我正在自动生成C代码来计算大型表达式,并试图用简单的例子弄清楚在单独的变量中预定义某些子部分是否有意义。 举个简单的例子,假设我们计算了一些forms: #include double test(double x, double y) { const double c[9][9] = { … }; // constants properly initialized, irrelevant double expr = c[0][0]*x*y + c[1][0]*pow(x,2)*y + … + c[8][0]*pow(x,9)*y + c[1][1]*pow(x,2)*pow(y,2) + … + c[8][1]*pow(x,9)*pow(y,2) + … 所有c [i] [j]正确初始化。 实际上,这些表达式包含数以千万计的乘法和加法。 现在提出一个同事 – 减少对pow()的调用次数并缓存表达式中经常需要的值 – 在单独的变量中定义x和y的每个幂,这没什么大不了的,因为代码是自动的无论如何生成,像这样: double xp2 = pow(x,2); double xp3 = […]