avatar
a*a
1
我在PentiumII上写一了一段C++程序,探索基本的vector运算在上面运行的效率。
程序做两种运算,一种是两个矢量逐个相乘,一种是两个矢量做内积。矢量的
长度在400-1000之间。时间量测是用rdtsc指令计算运行的时钟周期数。
结果出现了比较有意思的现象。
逐个相乘有着非常稳定的平均周期数,大概是8,几乎次次如此。求内积则不然。
不仅平均周期数在浮动漂移,而且有时候会蹦到很大的周期数。一般是11-14,最小
可到9,最大则到24。这可能是什么原因导致的呢?
avatar
a*a
2
发现可能是编译器的原因。导致这个问题的编译器是vc.net。
我换成Digital Mars就稳定多了。真是一个奇怪的问题。但是换成Digital Mars以后,
逐个相乘的周期数多了1,内积的周期数则稳定在13-15,这个结果似乎比较合理。
因为按道理,内积比逐个相乘每个节点多一个加法。

【在 a**a 的大作中提到】
: 我在PentiumII上写一了一段C++程序,探索基本的vector运算在上面运行的效率。
: 程序做两种运算,一种是两个矢量逐个相乘,一种是两个矢量做内积。矢量的
: 长度在400-1000之间。时间量测是用rdtsc指令计算运行的时钟周期数。
: 结果出现了比较有意思的现象。
: 逐个相乘有着非常稳定的平均周期数,大概是8,几乎次次如此。求内积则不然。
: 不仅平均周期数在浮动漂移,而且有时候会蹦到很大的周期数。一般是11-14,最小
: 可到9,最大则到24。这可能是什么原因导致的呢?

avatar
a*a
3
写这个程序的初衷是为了讨论Cache的对于计算速度的影响。刚才的程序都是只
调用一次子程序。后来调整一下,每次都连续调用两次子程序,但是只统计后一次
的计算时间,出现戏剧性的结果是,逐个相乘的每节点平均周期数没变,还是9,
但是内积则降为8! 这是什么结果呀!

【在 a**a 的大作中提到】
: 发现可能是编译器的原因。导致这个问题的编译器是vc.net。
: 我换成Digital Mars就稳定多了。真是一个奇怪的问题。但是换成Digital Mars以后,
: 逐个相乘的周期数多了1,内积的周期数则稳定在13-15,这个结果似乎比较合理。
: 因为按道理,内积比逐个相乘每个节点多一个加法。

avatar
a*a
4
可能。但是这里的问题是,所执行的两种运算所涉及到的元素都是一样的。都
从同样的连续地址中连续取数,只不过内积运算做了个在浮点堆栈上求和的运算,
而逐点乘积则是立即被赋回去。为什么会有这样的差别呢?
avatar
a*a
5
#include
#include
#include
#include
using namespace std;
class ValuesPool {
public:
typedef unsigned size_t;
static size_t roundup4(size_t sz) { return (sz + 3) & (~3); }
ValuesPool(const size_t size, double initVal=0) : size_(roundup4(size)), values_(new double[roundup4(size)]) {
register double val = initVal;
register double *const vals = values_;
for(size_t i=0; i
avatar
a*a
6
一个出乎意料的结果!为了方便增添新的功能,我把测试代码分别装到
两个子程序中,然后用main来调用。结果两个结果都很稳定,而且内积
的运算时间只有逐点乘积的一半!也就算是平均每点4个周期!4个周期!
一个取数操作,一个乘法操作,一个加法操作!我再到生成的汇编代码
去看,发现vc.net把我前次的内积(为了Cache)操作都优化没了。这下
得去买新眼镜去了!

【在 a**a 的大作中提到】
: #include
: #include
: #include
: #include
: using namespace std;
: class ValuesPool {
: public:
: typedef unsigned size_t;
: static size_t roundup4(size_t sz) { return (sz + 3) & (~3); }
: ValuesPool(const size_t size, double initVal=0) : size_(roundup4(size)), values_(new double[roundup4(size)]) {

avatar
t*n
7
After read your code, I can't figure out anything. So I was wondering
what the compiler did to the code. Maybe you can compile the code without
any optimization to see what happens this time. (Sorry I don't have any
of the compilers you mentioned. Can't test your code.:( )

【在 a**a 的大作中提到】
: 一个出乎意料的结果!为了方便增添新的功能,我把测试代码分别装到
: 两个子程序中,然后用main来调用。结果两个结果都很稳定,而且内积
: 的运算时间只有逐点乘积的一半!也就算是平均每点4个周期!4个周期!
: 一个取数操作,一个乘法操作,一个加法操作!我再到生成的汇编代码
: 去看,发现vc.net把我前次的内积(为了Cache)操作都优化没了。这下
: 得去买新眼镜去了!

avatar
a*a
8
可以试试Intel Compiler,对向量运算的优化很不错
但是需要P3或P4处理器

【在 a**a 的大作中提到】
: 我在PentiumII上写一了一段C++程序,探索基本的vector运算在上面运行的效率。
: 程序做两种运算,一种是两个矢量逐个相乘,一种是两个矢量做内积。矢量的
: 长度在400-1000之间。时间量测是用rdtsc指令计算运行的时钟周期数。
: 结果出现了比较有意思的现象。
: 逐个相乘有着非常稳定的平均周期数,大概是8,几乎次次如此。求内积则不然。
: 不仅平均周期数在浮动漂移,而且有时候会蹦到很大的周期数。一般是11-14,最小
: 可到9,最大则到24。这可能是什么原因导致的呢?

相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。