实现以下目标的最佳算法是什么:
0010 0000 => 0000 0100
转换从MSB-> LSB到LSB-> MSB.所有位必须反转; 也就是说,这不是字节顺序交换.
我一直在阅读div和mul组装操作,我决定通过在C中编写一个简单的程序来实现它们:
#include <stdlib.h>
#include <stdio.h>
int main()
{
size_t i = 9;
size_t j = i / 5;
printf("%zu\n",j);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
然后生成汇编语言代码:
gcc -S division.c -O0 -masm=intel
Run Code Online (Sandbox Code Playgroud)
但是看生成的division.s文件,它不包含任何div操作!相反,它通过位移和魔术数字来做某种黑魔法.这是一个计算代码片段i/5:
mov rax, QWORD PTR [rbp-16] ; Move i (=9) to RAX
movabs rdx, -3689348814741910323 ; Move some magic number to RDX (?)
mul rdx ; Multiply 9 by magic number
mov rax, rdx ; Take only the upper 64 bits of the …Run Code Online (Sandbox Code Playgroud) 我需要用LSB中的每个字节而不是MSB来反转YUV图像.我已经在C中读取了用于位反转的最佳算法(从MSB-> LSB到LSB-> MSB)但是我想做一些经过ARM优化的东西.
int8 *image;
for(i = 0; i < size; i++) {
image[i] = reversebit8(image[i]); //Use the lookup mechanism
}
Run Code Online (Sandbox Code Playgroud)
当我控制图像格式(双字节YUYV或任何排列)时,我可以反转16位:
int16 *image;
for(i = 0; i < size / 2; i++) {
image[i] = reversebit16(image[i]);
}
Run Code Online (Sandbox Code Playgroud)
图像从YUYV LSB到UYVY MSB.甚至是32位:
int32 *image;
for(i = 0; i < size / 4; i++) {
image[i] = reversebit32(image[i]);
}
Run Code Online (Sandbox Code Playgroud)
图像从YUYV LSB变为VYUY MSB.
问题:如何以优化的方式为ARM执行此操作?霓虹灯也很好.
我认为这些说明http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.kui0100a/armasm_cihjgdid.htm可能很有用.
是否有(快速)方法在avx2寄存器中执行32位int值的位反转?例如
_mm256_set1_epi32(2732370386);
<do something here>
//binary: 10100010110111001010100111010010 => 1001011100101010011101101000101
//register contains 1268071237 which is decimal representation of 1001011100101010011101101000101
Run Code Online (Sandbox Code Playgroud)