高手们讨论下这次的题目吧

aliceZOOZ 2007-08-02 01:41:31
大家都怎么做的那么快的。
第一题我读文件就要0.2s,不知道神人们怎么做到0.06s
第二题我要0.3s,参考了一些论文,用的是穷举+剪枝,但有很多人居然0s就出来了,不知道什么算法能这么快。
第三题我倒是能到0.016s,用的是传递闭包的算法,加了位操作和SSE2来计算。

还请各位高手不吝赐教
...全文
406 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
aliceZOOZ 2007-08-03
  • 打赏
  • 举报
回复
经大家的提示,第一题我写了一个用 SSE 的,
这里为了简单起见,假定数组是a,个数是num个,num是4的倍数。

__m128 mx = _mm_setzero_ps();
int idx[4] = {0};
for (int i = 0; i < num; i += 4)
{
__m128 t0 = _mm_loadu_ps(a + i + 0);
__m128 t1 = _mm_loadu_ps(a + i + 1);
t0 = _mm_mul_ps(t0, t1);
__m128 t2 = _mm_loadu_ps(a + i + 2);
__m128 t3 = _mm_loadu_ps(a + i + 3);
t2 = _mm_mul_ps(t2, t3);
t0 = _mm_mul_ps(t0, t2);
int mask = _mm_movemask_ps(_mm_cmpgt_ps(t0, mx));
if (mask != 0)
{
// 这个区域进来的很少,就不优化了。
mx = _mm_max_ps(t0, mx);
for (int k = 0; k <4; k++)
{
if (mask & (1<<k))
{
idx[k] = i + k;
}
}
}
}
__declspec(align(64)) float p[4] = {0};
_mm_store_ps(p, mx);
int id = 0;
for (int k = 0; k < 4; k++)
{
if (p[k] > p[id])
{
id = k;
}
}
printf("乘积=%f 首数的序号=%d\n", p[id], idx[id]);

这个速度比我以前简单相乘快一点。因为不能提交测试了,我估算了一下,加上使用 FileMapping,大概可以到0.17s左右。还是排不进前50。

huanyun 的方法听上去很不错,不知道速度有多快,另外能不能详细介绍一下,也让我们能好好学习一下。谢谢了~
huanyun 2007-08-03
  • 打赏
  • 举报
回复
等决赛名单公布后 我会公开自己的源码
第一题 用异步IO+SSE 或者FileMap+快速算法[取MaxMul/10000/10000/10000过滤减少乘法]
aliceZOOZ 2007-08-03
  • 打赏
  • 举报
回复
如果是1w或10w个顶点,可以考虑做个收缩强连通分支。
aliceZOOZ 2007-08-03
  • 打赏
  • 举报
回复
1000个顶点,用位操作,在他所测试的机器环境上,只要0.015s。而估计他测试程序运行时间的误差估计也差不多能有个10ms左右。
pengzhenwanli 2007-08-03
  • 打赏
  • 举报
回复
我认为确实没有读文件的时间,我的程序结果是这样的。
SIMD,你看一下连续4个数相乘,下一次相乘其实只改1个数的。

关于第2题,我认为0S,基本上不可能,不知道怎么做的。

第三题还没有想好,优化的不是很好。

yinming528 2007-08-03
  • 打赏
  • 举报
回复
如果真的有1000个顶点,图密集一些的话,差别就会很明显了。。。只怪intel的数据。。太。。。。*&#@$*&#@......唉···
aliceZOOZ 2007-08-03
  • 打赏
  • 举报
回复
第三题数据量不大,做那么多额外工作会得不偿失的。
yinming528 2007-08-03
  • 打赏
  • 举报
回复
我相信第三题收缩强联通分支,拓扑排序后,用二进制压位,是比传递闭包快很多的,虽然它们的渐进时间复杂度相同。
aliceZOOZ 2007-08-02
  • 打赏
  • 举报
回复
高手!
官方不是说不用改读文件的方法吗?看来又被骗了。

能介绍一下simd如何优化吗?我看了icl编译的代码,乘法用simd的单个数的乘法做的,貌似比fpu的快一丁点。simd我不是很熟悉,也不知道怎么做这种垂直的乘法。能举一个例子吗?
谢谢了!

btw: 这次前50的速度都在0.2s以下,为什么没什么讨论呢?记得冬天的那次比赛大家讨论的都很充分,比赛一结束都贴报告了。这些报告让人受益匪浅。这次是参加的人少了,还是大家觉得题目不值得讨论了?

godss 2007-08-02
  • 打赏
  • 举报
回复
内存映射能快1倍的样子,处理部分做得不好,simd有很多技巧的
aliceZOOZ 2007-08-02
  • 打赏
  • 举报
回复
to godss()
用内存映射后可以到多快?
另外这题怎么用simd的?不是4个相邻的乘吗?
godss 2007-08-02
  • 打赏
  • 举报
回复
1题都用内存映射的,交给操作系统去处理了,再加上SIMD指令
2就是拼剪枝,0s的很多是直接输出的
3用位运算,压缩成bit进行或操作,用多线程这里等待同步也比较麻烦些
aliceZOOZ 2007-08-02
  • 打赏
  • 举报
回复
>>读取文件的时间应该是不算的

做过的都知道,是算的。而且是主要时间。
至少我感觉是这样子。
pengzhenwanli 2007-08-02
  • 打赏
  • 举报
回复
第一题应该可以,读取文件的时间应该是不算的,使用SSE应该可以,好好计算一下,应该能节省下不少时间,我比较忙,就没有做。
第三题比较麻烦,传递闭包可以解决问题,但是cache miss太多,影响了算法,应该需要换新的算法,不然矩阵的数据来回在cache中颠倒,速度快不上去。

第二题我没有找到解决方案。自己想了一个,结果算我结果错误。
呵呵
aliceZOOZ 2007-08-02
  • 打赏
  • 举报
回复
原问其详
TopBoy_Neu 2007-08-02
  • 打赏
  • 举报
回复
总的说就是比赛有一些不成熟的地方,第一题再快一些也有可能.

568

社区成员

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

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