我正在尝试使用SIMD优化此功能,但我不知道从哪里开始.
long sum(int x,int y)
{
return x*x*x+y*y*y;
}
Run Code Online (Sandbox Code Playgroud)
反汇编函数如下所示:
4007a0: 48 89 f2 mov %rsi,%rdx
4007a3: 48 89 f8 mov %rdi,%rax
4007a6: 48 0f af d6 imul %rsi,%rdx
4007aa: 48 0f af c7 imul %rdi,%rax
4007ae: 48 0f af d6 imul %rsi,%rdx
4007b2: 48 0f af c7 imul %rdi,%rax
4007b6: 48 8d 04 02 lea (%rdx,%rax,1),%rax
4007ba: c3 retq
4007bb: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
Run Code Online (Sandbox Code Playgroud)
调用代码如下所示:
do {
for (i = 0; i < maxi; i++) { …Run Code Online (Sandbox Code Playgroud) 给定一个指向T的指针,我想确定T是否跨越N字节对齐的地址.在实践中我真的只关心0-5字节大小的对象是否跨越8或16字节字节边界,但我写了这个通用版本:
template<class T, unsigned long N>
bool straddlesBoundary(T* obj)
{
unsigned long before = (unsigned long)obj & ~(N-1);
unsigned long after = ((unsigned long)obj + sizeof(T) - 1) & ~(N-1);
return before != after;
}
Run Code Online (Sandbox Code Playgroud)
基本上,将地址向下舍入到最接近的N字节对齐地址,然后将指针增量乘以T的大小减1(因为T在下一个边界上的右边不算作跨骑)并将其向下舍入到最近N字节对齐的地址,如果匹配,则表示它不会跨越.
有更快的方法吗?我刚刚做了这个,我不知道是否有标准检查.
编辑:注意,我假设T小于N.
什么更有效,为什么?
具体地_mm_loadu_si128与_mm_load_si128在C.
(编者注:或者这是标记的程序集,可能它们意味着movdqu与movdqa手写的asm.这是不一样的,特别是没有AVX,因为_mm_load_si128可以编译成ALU指令的内存操作数而根本没有单独movdqa的.)
我想比较2 int8x8_t,从http://gcc.gnu.org/onlinedocs/gcc/ARM-NEON-Intrinsics.html
我们可以得到描述vclt_s8,但它没有告诉我们太多的细节.
`uint8x8_t vclt_s8 (int8x8_t, int8x8_t)`
Run Code Online (Sandbox Code Playgroud)
预期指令的形式:vcgt.s8 d0,d0,d0
返回值uint8x8_t,它让我感到困惑,因为我无法
if(vclt_s8(a, b))决定第一个是否更小.
那么假设我们有两个int8x8_t:int8x8_t a而且int8x8_t b,我们怎么知道它是否a更小?
我想isnan()在NEON内在函数中使用功能.Below是我的代码:input1,input2和输出类型为float.这些值从输入图像/帧的ROI更新.(图像处理示例)
for(x = 0;x<ht;x++){
for(y = 0;y<width;y++){
float a = (input1[x + (y * width)]);
float b = (input2[x + (y * width)]);
// check for division by zero
output = 0.0f;
if (!(isnan(a) | isnan(b) | (b == 0)))
{
output[x + (y * width)] = a / b;
}
}
Run Code Online (Sandbox Code Playgroud)
}
通过使用牛顿Raphson方法,我试图通过使用氖内在进行除法.但是我无法获得任何内在函数.isnan我得到了 __builtin_isnan()这不是一个内在函数.我怎么能isnan用于float32x4_t a和float32x4_t b
你好论坛 - 我有一些关于SIMD内在的类似/相关问题我在网上搜索了包括stackoverflow但没有找到好的答案所以请求你的帮助.
基本上我试图理解64位CPU如何在一次读取中获取所有128位,以及这种操作的要求是什么.
我试图使用SSE内部函数优化我的代码.在浏览完文档后,我发现__m128SSE中有浮点变量的数据类型,能够存储4个浮点数.__m128dSSE2中只有一个能够存储2个浮点数吗?这些变量有什么区别?SSE2不应该比SSE快吗?
我发现在为这个看似简单的问题创建代码时遇到了困难.
给定一个打包的8位整数,如果存在则用另一个字节替换另一个字节
举例来说,我想替换0x06用0x01,所以我可以做以下res的输入找到0x06:
// Bytes to be manipulated
res = _mm_set_epi8(0x00, 0x03, 0x02, 0x06, 0x0F, 0x02, 0x02, 0x06, 0x0A, 0x03, 0x02, 0x06, 0x00, 0x00, 0x02, 0x06);
// Target value and substitution
val = _mm_set1_epi8(0x06);
sub = _mm_set1_epi8(0x01);
// Find the target
sse = _mm_cmpeq_epi8(res, val);
// Isolate target
sse = _mm_and_si128(res, sse);
// Isolate remaining bytes
adj = _mm_andnot_si128(sse, res);
Run Code Online (Sandbox Code Playgroud)
现在我不知道如何继续or这两个部分,我需要删除目标并用替换的字节替换它.
我在这里缺少什么SIMD指令?
和其他问题一样,我只限于AVX,我没有更好的处理器.
我正在使用_mm_extract_epi8 (__m128i a, const int imm8)函数,它有const int参数.当我编译此c ++代码时,收到以下错误消息:
错误C2057预期的常量表达式
__m128i a;
for (int i=0; i<16; i++)
{
_mm_extract_epi8(a, i); // compilation error
}
Run Code Online (Sandbox Code Playgroud)
我怎么能在循环中使用这个功能?
我正在尝试编写C ++代码以使用SIMD进行矩阵乘法,但是结果是错误的,这是我的代码
void mat_sse(DATA m1[][SIZE], DATA m2[][SIZE], DATA mout[][SIZE])
{
DATA prod = 0;
__m128 X, Y, Z, M, N;
for(int i=0; i<SIZE; i=i+1){
Z[0] = Z[1] = Z[2] = Z[3] = 0;
for(int k=0; k< SIZE; k=k+4){
for( int j=0; j<SIZE; j=j+4){
X = _mm_load_ps(&m1[i][k]);
Y = _mm_load_ps(&m2[k][j]);
M = _mm_mul_ps(X, Y);
Z = _mm_add_ps(M, N);
mout[i][j] += Z[0];
mout[i][j+1] += Z[1];
mout[i][j+2] += Z[2];
mout[i][j+3] += Z[3];
}
}
}
return ;
}
Run Code Online (Sandbox Code Playgroud)
const int SIZE = 40; …