编写对具有n个元素的一维数组求和函数ArraySum()

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编写对具有n个元素的一维数组求和函数ArraySum()相关的知识,希望对你有一定的参考价值。

要求用指针作为函数参数,并在主函数main()中调用这个函数,实现对具有10个元素的一维数组求和。具体要求如下:
(1)用input()函数建立数组;
(2)用sum()函数对数组元素求和;
(3)用main()函数作为主控函数。

要求用指针作为函数参数,并在主函数main()中调用这个函数,实现对具有10个元素的一维数组求和。具体要求如下: (1)用input()函数建立数组; (2)用sum()函数对数组元素求和; (3)用main()函数作为主控函数。
void input(int *p,n)
int i;
for(i=0;i<n;i++)scanf("%d",p+i);

int sum(int*p,n)
int i,sum;
for(m=0,i=0;i<n;i++)sum+=*(p+i);
return sum;

main()
int a[10],n=10;
input(a,n);
printf("sum=%d\n",sum);
参考技术A #include<stdio.h>
#define N 10
void input(int *a,int n)  int i; for ( i=0;i<n;i++ ) scanf("%d",&a[i]); 
int sum(int *a,int n)  int i,s; s=0; for ( i=0;i<n;i++ ) s+=a[i]; return s; 
void main()  int a[N],s;
  input(a,N); s=sum(a,N); printf("%d\\n",s);

本回答被提问者采纳

使用共享内存对三维数组的一维求和

【中文标题】使用共享内存对三维数组的一维求和【英文标题】:Summation over one dimension of a three dimensional array using shared memory 【发布时间】:2012-04-01 12:47:05 【问题描述】:

我需要进行如下计算:A[x][y] = sum从 z=0 到 z=nB[x][y][z]+C[x][y][z ],其中矩阵 A 的维度为 [height][width],矩阵 B,C 的维度为 [height][width][n]。

值通过以下方式映射到内存:

index = 0;
for (z = 0; z<n; ++z)
    for(y = 0; y<width; ++y)
        for(x = 0; x<height; ++x) 
            matrix[index] = value;
            index++;
        

我想每个块计算一个总和,因为每个块都有自己的共享内存。为了避免数据竞争,我使用 atomicAdd,如下所示:

全局内存中的部分代码:

dim3 block (n, 1, 1);
dim grid (height, width, 1);

内核:

atomicAdd( &(A[blockIdx.x + blockIdx.y*gridDim.y]), 
           B[blockIdx.x + blockIdx.y*gridDim.y+threadIdx.x*blockDim.x*blockDim.y] 
           + C[blockIdx.x + blockIdx.y*gridDim.y+threadIdx.x*blockDim.x*blockDim.y] );

我想使用共享内存来计算总和,然后将此结果复制到全局内存。

我不确定如何使用共享内存来做这部分。在每个块的共享内存中将只存储一个数字(求和结果)。我应该如何将此数字复制到全局内存中 A 矩阵的正确位置?

【问题讨论】:

【参考方案1】:

您可能不需要共享内存或原子内存访问来进行您所询问的求和。如果我理解正确,您的数据按列主要顺序排列,因此逻辑操作是在输出矩阵中的每个矩阵条目都有一个线程,并让每个线程遍历输入矩阵的 z 轴,并在进行时求和。用于此的内核可能类似于:

__global__ void kernel(float *A, const float *B, const float *C, 
        const int width, const int height, const int n)

    int tidx = threadIdx.x + blockDim.x * blockIdx.x;
    int tidy = threadIdx.y + blockDim.y * blockIdx.y;

    if ( (tidx < height) && (tidy < width) ) 
        int stride = width * height;
        int ipos = tidx + tidy * height;

        float * oval = A + ipos;
        float sum = 0.f;
        for(int z=0; z<n; z++, ipos+=stride) 
            sum += B[ipos] + C[ipos];
        
        *oval = sum;
    

这种方法应该最适合具有width * height &gt;= n 的列主要数据。为此使用共享内存没有性能优势,也不需要使用原子内存操作。如果您遇到width * height &lt;&lt; n 的问题,尝试对每个求和进行逐块并行缩减可能是有意义的。但是你没有指出问题的典型维度是什么。如果您的问题更像后者,请发表评论,我可以在答案中添加基于缩减的示例内核。

【讨论】:

但是当每个线程遍历输入矩阵的 z 轴时,计算是序列化的,不是吗? 每个线程计算 z=0 中的值,然后移动到 z=1,依此类推。这是序列化的。并且对于每个 z 都必须访问全局内存。我想避免它。 在内核中,A 中的每个输出条目只有一次全局内存写入。每个线程从BC 执行n 读取。 BC 中的每个条目都被读取一次。没有更有效的方法来执行此操作。 如果您有 512x512xn 输入,那么我的答案中的代码是最好的方法。如果你有8x8x10^6,那么基于减少的策略是有意义的。 float * oval = A + ipos; ... ; *oval=sumA[ipos]=sum 具有相同的效果,只是我们不需要 ipos 的初始值 - 代码只是预先计算了总和需要的地址被存储以便ipos 可以在循环中更改。

以上是关于编写对具有n个元素的一维数组求和函数ArraySum()的主要内容,如果未能解决你的问题,请参考以下文章

python数组求和

Python / numpy:对数组的n个元素求和的最有效方法,以便每个输出元素是前n个输入元素的总和?

数组求和

C语言定义一个求数组n个元素的和的函数

c语言 .从键盘输入10个整数,存到一维数组中,并求这10个整数的和?

数组求和