- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我已经实现了标量矩阵加法内核。
#include <stdio.h>
#include <time.h>
//#include <x86intrin.h>
//loops and iterations:
#define N 128
#define M N
#define NUM_LOOP 1000000
float __attribute__(( aligned(32))) A[N][M],
__attribute__(( aligned(32))) B[N][M],
__attribute__(( aligned(32))) C[N][M];
int main()
{
int w=0, i, j;
struct timespec tStart, tEnd;//used to record the processiing time
double tTotal , tBest=10000;//minimum of toltal time will asign to the best time
do{
clock_gettime(CLOCK_MONOTONIC,&tStart);
for( i=0;i<N;i++){
for(j=0;j<M;j++){
C[i][j]= A[i][j] + B[i][j];
}
}
clock_gettime(CLOCK_MONOTONIC,&tEnd);
tTotal = (tEnd.tv_sec - tStart.tv_sec);
tTotal += (tEnd.tv_nsec - tStart.tv_nsec) / 1000000000.0;
if(tTotal<tBest)
tBest=tTotal;
} while(w++ < NUM_LOOP);
printf(" The best time: %lf sec in %d repetition for %dX%d matrix\n",tBest,w, N, M);
return 0;
}
在本例中,我使用不同的编译器标志编译了程序,内循环的汇编输出如下:
gcc -O2 msse4.2
:最佳时间:128X128 矩阵 406490 次重复中的 0.000024 秒
movss xmm1, DWORD PTR A[rcx+rax]
addss xmm1, DWORD PTR B[rcx+rax]
movss DWORD PTR C[rcx+rax], xmm1
gcc -O2 -mavx
:最佳时间:128X128 矩阵 1000001 次重复中的 0.000009 秒
vmovss xmm1, DWORD PTR A[rcx+rax]
vaddss xmm1, xmm1, DWORD PTR B[rcx+rax]
vmovss DWORD PTR C[rcx+rax], xmm1
AVX版本gcc -O2 -mavx
:
__m256 vec256;
for(i=0;i<N;i++){
for(j=0;j<M;j+=8){
vec256 = _mm256_add_ps( _mm256_load_ps(&A[i+1][j]) , _mm256_load_ps(&B[i+1][j]));
_mm256_store_ps(&C[i+1][j], vec256);
}
}
SSE版本gcc -O2 -sse4.2
::
__m128 vec128;
for(i=0;i<N;i++){
for(j=0;j<M;j+=4){
vec128= _mm_add_ps( _mm_load_ps(&A[i][j]) , _mm_load_ps(&B[i][j]));
_mm_store_ps(&C[i][j], vec128);
}
}
在标量程序中,-mavx
相对于 msse4.2
的加速是 2.7 倍。我知道 avx
有效地改进了 ISA,这可能是因为这些改进。但是,当我在 AVX
和 SSE
的内在函数中实现该程序时,速度提升了 3 倍。问题是:AVX 标量比 SSE 快 2.7 倍,当我对其进行矢量化时,速度提高了 3 倍(这个问题的矩阵大小为 128x128)。这有什么意义吗?在标量模式下使用 AVX 和 SSE 时,速度提高了 2.7 倍。但矢量化方法一定更好,因为我在 AVX 中处理 8 个元素,而在 SSE 中处理 4 个元素。根据 perf stat
报告,所有程序的缓存未命中率均低于 4.5%。
使用gcc -O2
、linux mint
、skylake
更新: 简而言之,Scalar-AVX 比 Scalar-SSE 快 2.7 倍,但 AVX-256 在矢量化时仅比 SSE-128 快 3 倍。我认为这可能是因为管道。在标量中,我有 3 个 vec-ALU,它们可能无法在矢量化模式下使用。我可能会比较苹果与橙子,而不是比较苹果与苹果,这可能是我无法理解原因的一点。
最佳答案
您所观察到的问题已得到解释 here 。在 Skylake 系统上,如果 AVX 寄存器的上半部分脏,则非 vex 编码的 SSE 操作对 AVX 寄存器的上半部分存在错误依赖性。就您而言,您的 glibc 2.23 版本似乎存在错误。在我的带有 Ubuntu 16.10 和 glibc 2.24 的 Skylake 系统上,我没有遇到这个问题。您可以使用
__asm__ __volatile__ ( "vzeroupper" : : : );
清理 AVX 寄存器的上半部分。我认为您不能使用诸如 _mm256_zeroupper
之类的内在函数来解决此问题,因为 GCC 会说它是 SSE 代码并且无法识别该内在函数。 -mvzeroupper
选项也不起作用,因为 GCC 再次认为它是 SSE 代码,并且不会发出 vzeroupper
指令。
顺便说一句,it's Microsoft's fault that the hardware has this problem .
<小时/>更新:
Other people are apparently encountering this problem on Skylake 。在 printf
之后观察到,memset
和clock_gettime
。
如果您的目标是将 128 位操作与 256 位操作进行比较,可以考虑使用 -mprefer-avx128 -mavx
(这在 AMD 上特别有用)。但这样你就会比较 AVX256 与 AVX128,而不是 AVX256 与 SSE。 AVX128和SSE都使用128位运算,但它们的实现不同。如果您进行基准测试,您应该提及您使用的是哪一个。
关于gcc - 在标量矩阵加法中使用 vaddss 代替 adds 有什么好处?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42324992/
我正在尝试将父 div 标记的最小宽度设置为内部所有子项的等效宽度。有办法吗? 例如, #sidebar{ width: 325px; } #content{ width: 500
我正在其中一个脚本中做一些附加操作,下面是一些简化的代码: foreach($entry in $arr){ ... switch($entry.AccessRights) { "GenericRea
float 在我的 Java/JOGL (OpenGL for Java) 程序中没有按预期计算。在绘制方法中,当调用每一帧(每秒 60 帧)时,我尝试修改对象的位置。所有值都是浮点值。 float
我正在尝试使用 C 中的结构为一个项目进行复杂的 vector 加法和点积。我已经编写了代码,但是,虽然它的编译没有问题,但一旦我运行我的程序,它就会停止工作。我还有该程序的其他部分,但这只是相关部分
这个问题已经有答案了: Use of java.math.MathContext (5 个回答) 已关闭 8 年前。 首先,我的搜索能力可能没有我希望的那么好,所以也许这种问题已经存在了。如果是的话请
PFB 说明问题的示例代码片段: var x=0.323; var cumulativeVal = 0; for(i=0;i<30;i++){
这个查询的每一步在 PostgreSQL 中的执行顺序是什么? SELECT SUM(field1)+SUM(field2)+SUM(field3)-SUM(field4); 据我所知,加法/减法是按
我正在尝试熟悉 Java 多线程应用程序。我试图想出一个可以很好地并行化的简单应用程序。我认为 vector 加法是一个很好的应用。但是,在我的 Linux 服务器(有 4 个内核)上运行时,我没有得
我在进行简单的加法并将值保存在变量中时遇到问题。 基本上我有以下代码: var accsen; var lowsev = parseInt(accsen); var hisev
所以我最近几个小时一直在解决一个问题,似乎无法阻止我的程序崩溃。问题是创建一个程序,该程序采用任意大小的矩阵,并且能够使用运算符重载将一个矩阵加到另一个矩阵上。当我尝试添加我类(class)的两个对象
我正在尝试添加以下内容,但它一直连接并返回一个字符串。 var nums = [1.99, 5.11, 2.99]; var total = 0; nums.forEach(f
我在网上搜索了数据仓库中加法、半加法和非加法度量之间的区别。我找到了一些结果,但我很难理解这些差异,因为它们不是一个例子。您能否通过示例向我更多地解释加法、半加法和非加法措施之间的区别。 最佳答案 T
%{control.current + #displayRows} 最终是我需要执行的语句。我将其放在 s:if 标记中,并使用 test 来查看该值是否在特定范围内。 最终,我得到的是字符串连接而不
请帮助我解释为什么下面的代码会得到奇怪的输出......为什么 getName() 得到 null。 输出: 列表检查:null:1 public class ListTest { public st
我需要通过字典生成校验和。键和值。 是否有任何简单的方法以迭代方式完成此任务。 foreach(dic.Keys 中的变量项) 校验和 += 校验和(dic[item]) + 校验和(item); 在
我想计算平均销售产品数量。表: pieces | date | status ------------------------------------------- 1
我正在尝试从 mysql 获取 INT 值并进行添加,最后更新数据库。不过这个好像没有更新?我该如何解决这个问题? $resultSecond = mysql_query("SELECT * FROM
我遇到了一个奇怪的问题。 有一张图片,我只需要重新计算非零像素。我想通过 numpy 来完成,因为我处理了数千张图像并且我需要它的速度。 这是一个维度较低的简化示例。 假设我有以下矩阵: [[0,
我不确定下一步该做什么。它们只是文本字段中的美元金额。我正在尝试将它们加在一起。 NSString *checkAmount = [checkAmountInput.text substringFro
我正在测试我的一些代码,在 javascript 中我添加了 .1+.2 ,它给了我 .30000000000000004 而不是 .3 。我不明白这一点。但是当我添加 .1+.3 时,它给了我 .4
我是一名优秀的程序员,十分优秀!