我目前有以下代码:
float a[4] = { 10, 20, 30, 40 };
float b[4] = { 0.1, 0.1, 0.1, 0.1 };
asm volatile("movups (%0), %%xmm0\n\t"
"mulps (%1), %%xmm0\n\t"
"movups %%xmm0, (%1)"
:: "r" (a), "r" (b));
Run Code Online (Sandbox Code Playgroud)
我首先要问几个问题:
(1)如果我要在16字节边界上对齐数组,它甚至可以工作吗?由于数组是在堆栈上分配的,因此对齐它们几乎是不可能的吗?
看到这篇文章的选定答案:堆栈变量是否由GCC __attribute __((aligned(x)))对齐?
(2)代码是否可以重构以提高效率?如果我将两个浮点数组都放在寄存器而不只是一个?
谢谢
我正在对一些SSE代码(将4个浮点数乘以4个浮点数)与传统的C代码进行基准测试.我认为我的基准代码在某种程度上必须是错误的,因为它似乎说非SSE代码比SSE快2-3倍.
有人能告诉我下面的基准测试代码有什么问题吗?并且可能建议另一种方法准确地显示SSE和非SSE代码的速度.
#include <time.h>
#include <string.h>
#include <stdio.h>
#define ITERATIONS 100000
#define MULT_FLOAT4(X, Y) ({ \
asm volatile ( \
"movaps (%0), %%xmm0\n\t" \
"mulps (%1), %%xmm0\n\t" \
"movaps %%xmm0, (%1)" \
:: "r" (X), "r" (Y)); })
int main(void)
{
int i, j;
float a[4] __attribute__((aligned(16))) = { 10, 20, 30, 40 };
time_t timer, sse_time, std_time;
timer = time(NULL);
for(j = 0; j < 5000; ++j)
for(i = 0; i < ITERATIONS; ++i) {
float b[4] …Run Code Online (Sandbox Code Playgroud) 我需要带有64位立即数地址的movlps指令,根据Intel手册,这应该是完全可能的。因此,如下所示:
movlps xmm0, [0x7fffffffffa0]
Run Code Online (Sandbox Code Playgroud)
但是我得到的是NASM将操作数大小截断为32位并打印相应的警告:
sample.s:6: warning: dword data exceeds bounds
Run Code Online (Sandbox Code Playgroud)
我尝试了不同形式的qword前缀,但没有成功。
如何使用SSE内在函数创建一个掩码,指示两个打包浮点(__m128)的符号是否相同,例如比较a和b,其中a为[1.0 -1.0 0.0 2.0],b为[1.0 1.0 1.0 1.0]我们得到的所需面具是[true false true true].
我想知道是否可以与x87并行使用SSE.所以考虑下面的伪代码,
1:sse_insn 2:x87_insn
管道是否会并行执行1和2,假设它们可以并行执行?
我总是渴望了解最极端的性能优化.最近,我一直在考虑开发大型寄存器.当我在64位寄存器中获得一位信息时,我感到内疚...所以我想知道如何一次比较多个16位的技巧(例如有用的时候很有可能没有)或类似的.对于检查至少一个元素是否设置了标志的最简单的例子是将这些64位与0寄存器进行xor并将其比较为> 0.在指令级别上,这将会利用instr.管道,但无论如何你只需要2个指令而不是128个(每个mov和cmp).多数民众赞成我称之为惊人的加速!
我知道缓存未命中是我们的cpus花费95%的时间,但我们假设缓存使用已经是最佳的.
特别是对于树,一次比较没有SIMD的多个值并获得单个childIndex以便下一步读取将是有用的.最后,指令应该最小化,并且不要因管道等待惩罚而受到太多损失.
我可以列出的其他操作:
当使用填充(例如5x11位)彼此相邻时,您可以并行执行5次加法,移位,减法和按位运算.或7x 8位.Ofc,需要以这种方式存储数据并有效地使用结果,而不会对位掩码提取/导入进行惩罚.
我有"荣幸"来改善其他人的以下代码的运行时间.(这是来自canny - 算法的非最大限制).我的第一个想法是使用SSE内在代码,我在这方面很新,所以我的问题是.
有没有机会这样做?如果是这样,有人可以给我一些提示吗?
void vNonMaximumSupression(
float* fpDst,
float const*const fpMagnitude,
unsigned char const*const ucpGradient, ///< [in] 0 -> 0°, 1 -> 45°, 2 -> 90°, 3 -> 135°
int iXCount,
int iXOffset,
int iYCount,
int ignoreX,
int ignoreY)
{
memset(fpDst, 0, sizeof(fpDst[0]) * iXCount * iXOffset);
for (int y = ignoreY; y < iYCount - ignoreY; ++y)
{
for (int x = ignoreX; x < iXCount - ignoreX; ++x)
{
int idx = iXOffset * y + x;
unsigned …Run Code Online (Sandbox Code Playgroud) 我有一个版本的OpenCV 2.4.10库,它是在Windows上为Intel X64构建的.
我怎么知道CV_SSE2是否有效?我没有代码.我只有libs,DLL和标题.
谢谢
我想矢量化以下操作:
V[i+1] = max(V[i] - c, V[i+1]) for i=1 to n-1 (V[0] = 0)
Run Code Online (Sandbox Code Playgroud)
相应的天真伪代码是:
for (i=0; i < n; i++) {
if (V[i]-c > V[i+1]) V[i+1] = V[i]-c
}
Run Code Online (Sandbox Code Playgroud)
哪些SIMD说明有用?
我尝试与SSE合作,但遇到了一些奇怪的行为。
我编写了简单的代码,用于将两个字符串与SSE Intrinsics进行比较,然后运行它并起作用。但是后来我明白了,在我的代码中,指针之一仍然没有对齐,但是我使用了_mm_load_si128指令,它要求指针在16字节边界上对齐。
//Compare two different, not overlapping piece of memory
__attribute((target("avx"))) int is_equal(const void* src_1, const void* src_2, size_t size)
{
//Skip tail for right alignment of pointer [head_1]
const char* head_1 = (const char*)src_1;
const char* head_2 = (const char*)src_2;
size_t tail_n = 0;
while (((uintptr_t)head_1 % 16) != 0 && tail_n < size)
{
if (*head_1 != *head_2)
return 0;
head_1++, head_2++, tail_n++;
}
//Vectorized part: check equality of memory with SSE4.1 instructions
//src1 - …Run Code Online (Sandbox Code Playgroud)