如果要方便进行菜鸟进行多核编程,最好开发一种支持线程组的高级语言

vuoin 2011-09-19 09:10:24
通常要改变多个对象的属性时,都是把它们放在一个数组中,然后加入一个循环,这样很方便,但是是串行操作。
如果有几十上百个核心,显然并行操作效率更高,但多线程同步太复杂,非得大牛才行,菜鸟们怎么伤得起?

线程组是一个奇异的函数,可以通过编译器自动把数组的每一个元素加入一个线程并且自动同步(整个线程组执行完以后再执行后面的代码)。
比如下列串行程序

for(i=0;i<100;i++)//一共有100个对象
{
vx[i]*=0.98;//第i个对象的横向速度受空气阻力的影响
vy[i]*=0.98;//第i个对象的竖向速度受空气阻力的影响
vy[i]+=0.01;//第i个对象的竖向速度受重力加速度的影响
x[i]+=vx[i];//第i个对象的横向位置因其横向速度而变化
y[i]+=vy[i];//第i个对象的竖向位置因其竖向速度而变化
}

可以写成以下并行程序

Threads(0:99)//Threads为线程函数,此时表示创建0到99号共100个线程
{
vx*=0.98;
vy*=0.98;
vy+=0.01;
x+=vx;
y+=vy;
}
/*编译器会自动
把{vx[0]*=0.98;vy[0]*=0.98;vy[0]+=0.01;x[0]+=vx[0];y[0]+=vy[0];}编入第0个线程
把{vx[1]*=0.98;vy[1]*=0.98;vy[1]+=0.01;x[1]+=vx[1];y[1]+=vy[1];}编入第1个线程
把{vx[2]*=0.98;vy[2]*=0.98;vy[2]+=0.01;x[2]+=vx[2];y[2]+=vy[2];}编入第2个线程
……
把{vx[99]*=0.98;vy[99]*=0.98;vy[99]+=0.01;x[99]+=vx[99];y[99]+=vy[99];}编入第99个线程

如果不要改变30到69号对象,线程函数还可以这样写

Threads(0:29,70:99)//Threads为线程函数,此时表示创建0到29号以及70到99号共100个线程
{
vx*=0.98;
vy*=0.98;
vy+=0.01;
x+=vx;
y+=vy;
}
/*编译器会自动
把{vx[0]*=0.98;vy[0]*=0.98;vy[0]+=0.01;x[0]+=vx[0];y[0]+=vy[0];}编入第0个线程
……
把{vx[29]*=0.98;vy[29]*=0.98;vy[29]+=0.01;x[29]+=vx[29];y[29]+=vy[29];}编入第29个线程
把{vx[70]*=0.98;vy[70]*=0.98;vy[70]+=0.01;x[70]+=vx[70];y[70]+=vy[70];}编入第70个线程
……
把{vx[99]*=0.98;vy[99]*=0.98;vy[99]+=0.01;x[99]+=vx[99];y[99]+=vy[99];}编入第99个线程
*/

如果各数组长度不等,调用Threads()函数则会创建出长度不同但仍然同步的线程,如果数组长度不够,则编译器自动按最长的数组创建线程,不会创建空线程。
...全文
153 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
intel_iclifort 2011-09-23
  • 打赏
  • 举报
回复
希望能更多地看到 CEAN 的使用
yosyg 2011-09-22
  • 打赏
  • 举报
回复
学习了.
intel_iclifort 2011-09-22
  • 打赏
  • 举报
回复
这里就拿其中的一个例子说明一下:

Example: FIR Scalar Code

for (i=0; i<M-K; i++){
s = 0
for (j=0; j<K; j++){
s+= x[i=j] * c[j];
}
y[i] = s;
}

Example: FIR Inner Loop Vector

for (i=0; i<M-K; i++){
y[i] = __sec_reduce_add(x[i:K] * c[0:K]);
}

Example: FIR Outer Loop Vector
y[0:M-K] = 0;
for (j=0; j<K; j++){
y[0:M-K]+= x[j:M-K] * c[j];
}


Example: Using C99 restrict Pointer

void saxpy_vec(int m, float a, float (&x)[m], float(&y)[m]){
y[:] += a * x[:]; // x may overlap with y,
// temporary array t[n] allocated by the compiler
// t[:] = y[:] + a * x[:]; y[:] = t[:]
}

void saxpy_vec(int m, float a, float restrict *x, float(&y)[m]){
y[:] += a * x[0:m]; // x and y are disjointed, no temporary array
}



详细地关于 CEAN 编程模式的讨论,请参考icc 编译器手册 http://software.intel.com/sites/products/documentation/studio/composer/en-us/2011/compiler_c/index.htm#optaps/common/optaps_par_cean_using.htm

vuoin 2011-09-22
  • 打赏
  • 举报
回复
是不是简洁,你倒是写出来看看啊!别光说不练。
vuoin 2011-09-22
  • 打赏
  • 举报
回复
是不是简洁,你倒是写出来看看啊!别光说不练。
vuoin 2011-09-20
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 intel_iclifort 的回复:]
利用CEAN改写代码后,能够更加容易地让编译器完成向量优化。而且代码也很简洁直观,值得试试
[/Quote]
写出来看看
intel_iclifort 2011-09-20
  • 打赏
  • 举报
回复
利用CEAN改写代码后,能够更加容易地让编译器完成向量优化。而且代码也很简洁直观,值得试试
vuoin 2011-09-19
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 intel_iclifort 的回复:]
试过 CEAN (array notation)吗? 这个功能在 icc 12.0 已经实现了 :)
[/Quote]


Threads(0:29,70:99)//Threads为线程组函数,此时表示创建0到29号以及70到99号共100个线程
{
vx*=0.98;
vy*=0.98;
vy+=0.01;
x+=vx;
y+=vy;
}
/*编译器会自动
把{vx[0]*=0.98;vy[0]*=0.98;vy[0]+=0.01;x[0]+=vx[0];y[0]+=vy[0];}编入第0个线程
……
把{vx[29]*=0.98;vy[29]*=0.98;vy[29]+=0.01;x[29]+=vx[29];y[29]+=vy[29];}编入第29个线程
把{vx[70]*=0.98;vy[70]*=0.98;vy[70]+=0.01;x[70]+=vx[70];y[70]+=vy[70];}编入第70个线程
……
把{vx[99]*=0.98;vy[99]*=0.98;vy[99]+=0.01;x[99]+=vx[99];y[99]+=vy[99];}编入第99个线程
*/

改写成CEAN (array notation)形式看看
intel_iclifort 2011-09-19
  • 打赏
  • 举报
回复
试过 CEAN (array notation)吗? 这个功能在 icc 12.0 已经实现了 :)

567

社区成员

发帖
与我相关
我的任务
社区描述
英特尔® 边缘计算,聚焦于边缘计算、AI、IoT等领域,为开发者提供丰富的开发资源、创新技术、解决方案与行业活动。
社区管理员
  • 英特尔技术社区
  • shere_lin
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧