AVX512CD包含内部函数,_mm512_conflict_epi32(__m512i a)它返回一个向量,a如果它具有相同的值,则为其中的每个元素设置.有没有办法在AVX2中做类似的事情?
我对extact位不感兴趣,我只需要知道哪些元素是左侧(或右侧)元素的重复.我只需要知道分散是否会发生冲突.
基本上我需要一个AVX2等价物
__mm256i detect_conflict(__mm256i a) {
__mm256i cd = _mm256_conflict_epi32(a);
return _mm256_cmpgt_epi32(cd, _mm256_set1_epi32(0));
}
Run Code Online (Sandbox Code Playgroud)
我能想到的唯一方法是使用_mm256_permutevar8x32_epi32()将每个值向右移动1(跨越通道),然后进行七次比较,屏蔽掉未经过的位,而不是将_mm256_or_si256()它们放在一起,这是非常慢的.
在玩godbolt.org时,我注意到gcc(6.2,7.0快照),clang(3.9)和icc(17)在编译接近于
int a(int* a, int* b) {
if (b - a < 2) return *a = ~*a;
// register intensive code here e.g. sorting network
}
Run Code Online (Sandbox Code Playgroud)
将(-O2/-O3)编译成这样的东西:
push r15
mov rax, rcx
push r14
sub rax, rdx
push r13
push r12
push rbp
push rbx
sub rsp, 184
mov QWORD PTR [rsp], rdx
cmp rax, 7
jg .L95
not DWORD PTR [rdx]
.L162:
add rsp, 184
pop rbx
pop rbp
pop r12
pop r13
pop r14
pop r15
ret
Run Code Online (Sandbox Code Playgroud)
这显然在b …
我得到并切换这样的语句:
switch(x){
case a:
executeSth();
executeA();
break;
case b:
executeSth();
executeB();
break;
...
}
Run Code Online (Sandbox Code Playgroud)
所以executeSth(); 应该总是执行,除非在默认情况下,但在它之后调用一些特定于案例的代码(executeA();或executeB()等).(所以简单地将它放在开关前面是行不通的).
有没有一种有效的方法来减少"executeSth();"的数量 在不牺牲性能的情况下?
我只能想象将它分成两个开关(一个执行executeSth()和一个执行特定代码)但这会牺牲性能.也许你有更好的想法?
我基本上习惯于c/c ++或php的代码.我的目标是最小化代码大小,并在c/c ++的情况下最小化生成的可执行文件的大小.
编辑:是的,功能的顺序很重要.Edit2:我没有php或c ++之间的选择,我需要它尽可能好.