我试图在L1缓存中获得全部带宽,以便在Intel处理器上实现以下功能
float triad(float *x, float *y, float *z, const int n) {
float k = 3.14159f;
for(int i=0; i<n; i++) {
z[i] = x[i] + k*y[i];
}
}
Run Code Online (Sandbox Code Playgroud)
这是STREAM的三合一功能.
使用具有此功能的SandyBridge/IvyBridge处理器可获得约95%的峰值(使用NASM组装).但是,除非我展开循环,否则使用Haswell I仅达到峰值的62%.如果我展开16次,我得到92%.我不明白这一点.
我决定使用NASM在汇编中编写我的函数.装配中的主循环看起来像这样.
.L2:
vmovaps ymm1, [rdi+rax]
vfmadd231ps ymm1, ymm2, [rsi+rax]
vmovaps [rdx+rax], ymm1
add rax, 32
jne .L2
Run Code Online (Sandbox Code Playgroud)
在示例12.7-12.11 中的Agner Fog的优化组装手册中,他y[i] = y[i] +k*x[i]对Pentium M,Core 2,Sandy Bridge,FMA4和FMA3 做了几乎相同的事情(但是).我设法或多或少地自己重现了他的代码(实际上他在广播时在FMA3示例中有一个小错误).除FMA4和FMA3外,他为每个处理器的表格提供指令大小计数,融合操作,执行端口.我曾试图为FMA3制作这张桌子.
ports
size ?ops-fused 0 1 2 3 4 5 6 7
vmovaps 5 1 ½ ½ …Run Code Online (Sandbox Code Playgroud) 我启用时GCC会收集哪些信息-fprofile-generate,哪些优化确实使用了收集的信息(设置-fprofile-use标志时)?
我需要引用这里.我已经搜索了一段时间,但没有找到任何记录.
有关链接时间优化(LTO)的信息将是一个加号!= d
有谁知道为什么GCC/Clang不会在下面的代码示例中优化函数test1,只是在使用fast-math选项时只使用RCPPS指令?是否有另一个编译器标志会生成此代码?
typedef float float4 __attribute__((vector_size(16)));
float4 test1(float4 v)
{
return 1.0f / v;
}
Run Code Online (Sandbox Code Playgroud)
您可以在此处查看已编译的输出:https://goo.gl/jXsqat
因此,对于我在计算机系统课程中的最终作业,我们需要优化这些forloops,使其比原始版本更快.使用我们的linux服务器,基本等级不到7秒,完整等级不到5秒.我在这里的代码大约需要5.6秒.我想我可能需要以某种方式使用指针来使它更快,但我不是很确定.任何人都可以提供我的任何提示或选项吗?非常感谢!
QUICKEDIT:文件必须保持50行或更少,我忽略了教师所包含的那些注释行.
#include <stdio.h>
#include <stdlib.h>
// You are only allowed to make changes to this code as specified by the comments in it.
// The code you submit must have these two values.
#define N_TIMES 600000
#define ARRAY_SIZE 10000
int main(void)
{
double *array = calloc(ARRAY_SIZE, sizeof(double));
double sum = 0;
int i;
// You can add variables between this comment ...
register double sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0, sum5 = 0, …Run Code Online (Sandbox Code Playgroud) 我试图改变这个代码来处理std::vector<int>.
float accumulate(const std::vector<float>& v)
{
// copy the length of v and a pointer to the data onto the local stack
const size_t N = v.size();
const float* p = (N > 0) ? &v.front() : NULL;
__m128 mmSum = _mm_setzero_ps();
size_t i = 0;
// unrolled loop that adds up 4 elements at a time
for(; i < ROUND_DOWN(N, 4); i+=4)
{
mmSum = _mm_add_ps(mmSum, _mm_loadu_ps(p + i));
}
// add up single values until all …Run Code Online (Sandbox Code Playgroud) 在我的程序中,我需要申请__attribute__(( aligned(32)))一个int *或float *
我试过这样但我不确定它会起作用。
int *rarray __attribute__(( aligned(32)));
Run Code Online (Sandbox Code Playgroud)
我看到了这个,但没有找到答案
假设我有两个向量a和b,存储为向量.我想制作a += b或者a +=b * k,数字在哪里k.
我可以肯定做到以下几点,
while (size--) {
(*a++) += (*b++) * k;
}
Run Code Online (Sandbox Code Playgroud)
但是,有哪些方法可以轻松利用SSD2等SIMD指令?