我有一个做图像处理的大型数字运算程序。它主要是卷积。它是用C++编写的,用Mingw GCC 4.8.1编译。我在一台装有英特尔酷睿i7 4900 MQ的笔记本电脑上运行它(SSE高达SSE 4.2和AVX 2)。当我告诉GCC使用SSE优化(使用-march=native -mfpmath=sse -msse 2)时,与使用默认的x87 FPU相比,我没有看到加速。当我使用双精度而不是浮点数时,没有减速。我的理解是,当使用浮点数而不是双倍时,SSE应该给我给予2倍的加速。我错了吗?
fxnxkyjh1#
我的理解是,当使用浮点数而不是双倍时,SSE应该给我给予2倍的加速。我错了吗?你有编译器和你的代码一样好-记住这一点。如果你没有在设计算法时考虑到向量化,编译器是无能为力的。这并不容易:“打开开关,享受100%的性能提升”。首先,用-ftree-vectorizer-verbose=N编译代码,看看编译器到底向量化了什么。N是verbosity级别,让5看到所有可用的输出(更多信息can be found here)。此外,您可能想了解GCC的矢量化器。请记住,对于性能关键的代码部分,直接使用SSE/AVX内部函数(brilliantly documented here)可能是最好的选择。
-ftree-vectorizer-verbose=N
N
5
ykejflvf2#
没有代码,没有关于测试程序的描述,但通常可以这样解释:1.这不仅仅是cpu的限制,它也受到内存速度的限制。图像处理通常有很大的工作集,超过了你的非至强cpu的缓存量。最终cpu遇到饥饿意味着整体吞吐量可以受到内存速度的限制。1.你可能使用了一个对矢量化不友好的算法。并不是每个算法都能从矢量化中受益。有很多条件需要满足-流依赖性,内存布局等。
slmsl1lt3#
有一个外部的机会,这是有关我的问题与系统库分布与Mingw GCC端口使用x87 80位FP内部。基于几个随机测试片段,我认为从纯x87代码到SSE 2或更高的双精度代码的改进应该是算术重代码的25%左右,而浮点数比双精度代码快40%。
double BM_Pi(double x) { int n = 20; double f = 1; while (--n) f = (2 * n - 1) + n * n / f; // phi has f = 1 + 1 /(f + 1) here return 4/f; }
字符串通过假装是i586来强制生成x87代码,然后允许所有优化-O3这些是我必须掌握的不同编译器的结果:| 编译器|Phi| Pi|| --|--|--|| 英特尔avx 2| 30 | 77 || MS AVX2| 63 | 102 || MS x87| 84 | 115 || GCC AVX2| 61 | 95 || GCC x87| 83 | 116 |我在一些内存密集型(不支持向量)代码上看到的是,SSE 2 FP有时比AVX快20%,比AVX 2快10%。这显然是非常依赖于代码的。英特尔编译器可能已经找到了一种方法来向量化Phi测试(确切的两倍快是可疑的)。
3条答案
按热度按时间fxnxkyjh1#
我的理解是,当使用浮点数而不是双倍时,SSE应该给我给予2倍的加速。我错了吗?
你有
编译器和你的代码一样好-记住这一点。如果你没有在设计算法时考虑到向量化,编译器是无能为力的。这并不容易:“打开开关,享受100%的性能提升”。
首先,用
-ftree-vectorizer-verbose=N
编译代码,看看编译器到底向量化了什么。N
是verbosity级别,让5
看到所有可用的输出(更多信息can be found here)。此外,您可能想了解GCC的矢量化器。
请记住,对于性能关键的代码部分,直接使用SSE/AVX内部函数(brilliantly documented here)可能是最好的选择。
ykejflvf2#
没有代码,没有关于测试程序的描述,但通常可以这样解释:
1.这不仅仅是cpu的限制,它也受到内存速度的限制。图像处理通常有很大的工作集,超过了你的非至强cpu的缓存量。最终cpu遇到饥饿意味着整体吞吐量可以受到内存速度的限制。
1.你可能使用了一个对矢量化不友好的算法。并不是每个算法都能从矢量化中受益。有很多条件需要满足-流依赖性,内存布局等。
slmsl1lt3#
有一个外部的机会,这是有关我的问题与系统库分布与Mingw GCC端口使用x87 80位FP内部。
基于几个随机测试片段,我认为从纯x87代码到SSE 2或更高的双精度代码的改进应该是算术重代码的25%左右,而浮点数比双精度代码快40%。
字符串
通过假装是i586来强制生成x87代码,然后允许所有优化-O3这些是我必须掌握的不同编译器的结果:
| 编译器|Phi| Pi|
| --|--|--|
| 英特尔avx 2| 30 | 77 |
| MS AVX2| 63 | 102 |
| MS x87| 84 | 115 |
| GCC AVX2| 61 | 95 |
| GCC x87| 83 | 116 |
我在一些内存密集型(不支持向量)代码上看到的是,SSE 2 FP有时比AVX快20%,比AVX 2快10%。这显然是非常依赖于代码的。英特尔编译器可能已经找到了一种方法来向量化Phi测试(确切的两倍快是可疑的)。