首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SSE移位整数

SSE移位整数
EN

Stack Overflow用户
提问于 2010-11-14 14:37:20
回答 1查看 2K关注 0票数 0

我试图理解SSE的转换是如何工作的,但我不理解gdb给我的输出。使用SSE4,我有一个包含8个16位无符号整数的128位向量(使用uint16_t)。然后,我使用内在的_mm_cmpgt_epi16将它们与某些值进行比较,这个函数将所有0或1位放入用于存储ints的位中。到目前为止,使用gdb我得到:

代码语言:javascript
复制
(gdb) p/t sse_res[0]
$3 = {1111111111111111111111111111111111111111111111110000000000000000, 1111111111111111111111111111111111111111111111110000000000000000}

那么我想把它们移到右边(对吗?)所以我只得到一个1的数值,以防万一是真的。然后,GDB给我一个我不明白的输出:

代码语言:javascript
复制
(gdb) p/t shifted
$4 = {11101000000000010010000000000000110000000000000000011, 100111000000000001011000000000001001000000000000001111}

它甚至和第一个不一样长,为什么呢?为了试一试,我使用了以下内在特性将其稍微移向右边:

代码语言:javascript
复制
shifted = _mm_srli_epi16(sse_array[i], 1);

我预计它会在每16位块的右端移动一个零位。

更新:

我编写了一个用位掩码测试这个东西的小例子,它工作得很好,但我仍然不理解gdbs的行为:

代码语言:javascript
复制
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>

#include <tmmintrin.h> 
#include <smmintrin.h>

void print128_num(__m128i vector)
{
    uint16_t *values = (uint16_t*) &vector;
    printf("Numerical: %i %i %i %i %i %i %i %i \n", 
           values[0], values[1], values[2], values[3], values[4], values[5], 
           values[6], values[7]);
}

int main (int argc, char **argv)
{
    uint16_t nums[] = {1, 57, 33, 22, 88, 99, 9, 73};

    __m128i *nums_sse = (__m128i*)(&nums);
    print128_num(*nums_sse);

    // vector of 42
    __m128i mm42 = _mm_set1_epi16(42);

    __m128i sse_res = _mm_cmpgt_epi16(*nums_sse, mm42);
    printf("Result of the comparison\n");
    print128_num(sse_res);

    // bitmask
    __m128i mask = _mm_set1_epi16(1);

    __m128i finally = _mm_and_si128(sse_res, mask);
    printf("Result of the masking\n");
    print128_num(finally);

    uint16_t* sse_ptr = (uint16_t*)(&finally);

    uint32_t result = sse_ptr[0] + sse_ptr[1] + sse_ptr[2] + sse_ptr[3]
                    + sse_ptr[4] + sse_ptr[5] + sse_ptr[6] + sse_ptr[7];

    printf("Result: %i numbers greater 42\n", result);

    return 0;
}

代码语言:javascript
复制
Breakpoint 1, main (argc=1, argv=0x7fff5fbff3b0) at example_comp.c:44
44      printf("Result: %i numbers greater 42\n", result);
(gdb) p/t sse_res
$1 = {11111111111111110000000000000000, 1111111111111111000000000000000011111111111111111111111111111111}
(gdb) p/t mask
$2 = {1000000000000000100000000000000010000000000000001, 1000000000000000100000000000000010000000000000001}
(gdb) p/t finally
$3 = {10000000000000000, 1000000000000000000000000000000010000000000000001}
(gdb) p result
$4 = 4
(gdb) 

我的gdb版本:GNU gdb 6.3.50-20050815 (Apple version gdb-1472) (Wed Jul 21 10:53:12 UTC 2010)

编译器标志:-Wall -g -O0 -mssse3 -msse4 -std=c99

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-11-14 19:12:27

我不明白你到底在做什么,但也许你可以帮我们澄清一下。

因此,在两个变量中的每个变量中都有8个有符号整数,测试结果大于。结果显示,前3位更大,下一位更大,下一位更大,最后一位不是。(_mm_cmpgt_epi16在我找到的引用中假定有符号整数。)

然后你想知道“这”是不是真的,但我不知道你这么说是什么意思。你是说他们都更伟大吗?(如果是这样,那么您只需将结果与MAX_VALUE或-1或类似的结果进行比较。)

但最后一步是将一些数据转到正确的分段。注意,这不是与sse_res相同的变量。你是想把那个换掉吗?

在移动之前,我们不知道数据中有什么,我们无法判断它是否正确工作,但我假设gdb在其输出中忽略了前导零,这将解释较短的结果。

代码语言:javascript
复制
0000000000011101    29    was 58 or 59
0000000000100100    36    was 72 or 73
0000000000011000    24    was 48 or 49
0000000000000011     3    was  6 or  7
0000000000100111    39    was 78 or 79
0000000000010110    22    was 44 or 45
0000000000100100    36    was 72 or 73
0000000000001111    15    was 30 or 31

这些数字看起来眼熟吗?

更新:

谢谢你更新的代码。它看起来整数按相反的顺序包装,而gdb输出中的前导零点仍未结束。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4177946

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档