我试图对包含在数学库中使用'pow'函数的循环进行矢量化.我知道英特尔编译器支持使用'pow'作为sse指令 - 但我似乎无法使用gcc运行(我认为).这是我正在使用的情况:
int main(){
int i=0;
float a[256],
b[256];
float x= 2.3;
for (i =0 ; i<256; i++){
a[i]=1.5;
}
for (i=0; i<256; i++){
b[i]=pow(a[i],x);
}
for (i=0; i<256; i++){
b[i]=a[i]*a[i];
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我正在编译以下内容:
gcc -O3 -Wall -ftree-vectorize -msse2 -ftree-vectorizer-verbose=5 code.c -o runthis
Run Code Online (Sandbox Code Playgroud)
这是在使用gcc版本4.2的os X 10.5.8上(我也使用4.5并且无法判断它是否已经向量化了 - 因为它根本没有输出任何内容).似乎没有一个循环矢量化 - 是否存在一个对齐问题或者我需要使用限制的其他问题?如果我将其中一个循环写为函数,我会得到更详细的输出(代码):
void pow2(float *a, float * b, int n) {
int i;
for (i=0; i<n; i++){
b[i]=a[i]*a[i];
}
}
Run Code Online (Sandbox Code Playgroud)
输出(使用7级详细输出):
note: not vectorized: can't determine dependence between *D.2878_13 …Run Code Online (Sandbox Code Playgroud) 我试图追踪寄存器的使用情况,并遇到了一个有趣的场景.请考虑以下来源:
#define OL 20
#define NHS 10
__global__ void loop_test( float ** out, const float ** in,int3 gdims,int stride){
const int idx = blockIdx.x*blockDim.x + threadIdx.x;
const int idy = blockIdx.y*blockDim.y + threadIdx.y;
const int idz = blockIdx.z*blockDim.z + threadIdx.z;
const int index = stride*gdims.y*idz + idy*stride + idx;
int i = 0,j =0;
float sum =0.f;
float tmp;
float lf;
float u2, tW;
u2 = 1.0;
tW = 2.0;
float herm[NHS];
for(j=0; j < OL; ++j){
for(i = 0; …Run Code Online (Sandbox Code Playgroud) 我怎么能够:
下面是一个应该完成此任务的代码.请注意,对于NxN数组大小,我的代码可以正常工作.对于N!M,其中N!= M,我的代码咬了灰尘(不是正确的结果).如果你能解决这个问题,我将奖励你1个互联网(供应有限).也许我很疯狂,但根据文档,这应该工作(它确实适用于方阵!).附加的代码应该与'nvcc whateveryoucallit.cu -o runit'一起运行.
感谢帮助!
#include<stdio.h>
#include<cuda.h>
#include<iostream>
#define height 16
#define width 11
#define BLOCKSIZE 16
using namespace std;
// Device Kernels
//Texture reference Declaration
texture<float,2> texRefEx;
__global__ void kernel_w_textures(float* devMPPtr, float * devMPtr, int pitch)
{
// Thread indexes
unsigned int idx = blockIdx.x*blockDim.x + threadIdx.x;
unsigned int idy = blockIdx.y*blockDim.y + threadIdx.y;
// Texutre Coordinates
float u=(idx)/float(width);
float v=(idy)/float(height);
devMPtr[idy*width+idx]=devMPPtr[idy*pitch/sizeof(float)+idx];
// Write Texture Contents to malloc array +1
devMPtr[idy*width+idx]= tex2D(texRefEx,u,v);//+1.0f; …Run Code Online (Sandbox Code Playgroud) 两部分我的问题.哪个更有效/更快:
int a,b,c,d,e,f;
int a1,b1,c1,d1,e1,f1;
int SumValue=0; // oops forgot zero
// ... define all values
SumValue=a*a1+b*b1+c*c1+d*d1+e*e1*f*f1;
Run Code Online (Sandbox Code Playgroud)
要么
Sumvalue+=a*a1+b*b1+c*c1;
Sumvalue+=d*d1+e*e1*f*f1;
Run Code Online (Sandbox Code Playgroud)
我猜第一个是.我的第二个问题是为什么.
我想第三个问题是,在任何时候都需要打破一个加法运算(除了编译器对行连续数的限制等等).
编辑
是否只有当整个算术运算无法适应缓存时,我才会看到减速?我认为这是不可能的 - 在这种情况发生之前,编译器可能会因为两次线路延续而感到生气.也许我明天要玩,看看.