我有这个简单的二进制搜索成员函数,在那里lastIndex,nIter并且xi是类成员:
uint32 scalar(float z) const
{
uint32 lo = 0;
uint32 hi = lastIndex;
uint32 n = nIter;
while (n--) {
int mid = (hi + lo) >> 1;
// defining this if-else assignment as below cause VS2015
// to generate two cmov instructions instead of a branch
if( z < xi[mid] )
hi = mid;
if ( !(z < xi[mid]) )
lo = mid;
}
return lo;
}
Run Code Online (Sandbox Code Playgroud)
gcc和VS 2015都将内循环转换为代码流分支:
000000013F0AA778 movss xmm0,dword …Run Code Online (Sandbox Code Playgroud) 使用sse2或avx比较操作返回所有零或全部的位掩码(例如_mm_cmpge_pd返回__m128d.
我找不到avx512的等价物.比较操作似乎只返回短位掩码.语义是否发生了根本变化,或者我遗漏了什么?
有类似标题的问题,但我的问题涉及其他地方没有涉及的一个非常具体的用例.
我有4个__128d寄存器(x0,x1,x2,x3),我想在5 __256d寄存器(y0,y1,y2,y3,y4)中重新组合它们的内容,如下所示,准备其他计算:
on entry:
x0 contains {a0, a1}
x1 contains {a2, a3}
x2 contains {a4, a5}
x3 contains {a6, a7}
on exit:
y0 contains {a0, a1, a2, a3}
y1 contains {a1, a2, a3, a4}
y2 contains {a2, a3, a4, a5}
y3 contains {a3, a4, a5, a6}
y4 contains {a4, a5, a6, a7}
Run Code Online (Sandbox Code Playgroud)
我在下面的实现很慢.有没有更好的办法?
y0 = _mm256_set_m128d(x1, x0);
__m128d lo = _mm_shuffle_pd(x0, x1, 1);
__m128d hi = _mm_shuffle_pd(x1, x2, 1);
y1 = _mm256_set_m128d(hi, lo);
y2 = _mm256_set_m128d(x2, x1);
lo = …Run Code Online (Sandbox Code Playgroud) 我正在处理第三方C++库,它广泛使用模板.这使得很难为我的框架使用它创建一个C API.
提取问题,假设库提供了以下功能:
template <int i> void foo();
template <int i> void zoo(int v);
Run Code Online (Sandbox Code Playgroud)
我想用函数头创建一个C API:
extern "C" void c_foo(int i);
extern "C" void c_zoo(int i, int v);
Run Code Online (Sandbox Code Playgroud)
一个明显的实现可能是:
void c_foo(int i)
{
switch(i) {
case 1: foo<1>(); break;
case 2: foo<2>(); break;
case 3: foo<3>(); break;
default: break;
};
};
Run Code Online (Sandbox Code Playgroud)
并做同样的事情void zoo(int).
如果可能值的范围i很小,这可以正常工作.如果我想处理i[1,100]中的所有可能值,那么以这种方式编写代码变得非常难看,因为有很多重复.
有没有更紧凑的方法来做到这一点,即编写更少的代码行?也许使用递归预处理器宏?