Uint8 ~ mm0 레지스터

Awerde

저는 프레젠테이션 의 예를 가지고 놀았습니다 (슬라이드 41).

내가 아는 한 알파 블렌딩을 수행합니다.

MOVQ mm0, alpha//4 16-b zero-padding α
MOVD mm1, A //move 4 pixels of image A 
MOVD mm2, B //move 4 pixels of image B
PXOR mm3 mm3 //clear mm3 to all zeroes 
//unpack 4 pixels to 4 words
PUNPCKLBW mm1, mm3 // Because B -A could be
PUNPCKLBW mm2, mm3 // negative, need 16 bits
PSUBW mm1, mm2 //(B-A) 
PMULHW mm1, mm0 //(B-A)*fade/256 
PADDW mm1, mm2 //(B-A)*fade + B 
//pack four words back to four bytes
PACKUSWB mm1, mm3

어셈블러를 사용하여 c로 다시 작성하고 싶습니다.

지금은 다음과 같습니다.

void fade_mmx(SDL_Surface* im1,SDL_Surface* im2,Uint8 alpha, SDL_Surface* imOut)
{
    int pixelsCount = imOut->w * im1->h;
    
    Uint32 *A = (Uint32*) im1->pixels;
    Uint32 *B = (Uint32*) im2->pixels;
    Uint32 *out = (Uint32*) imOut->pixels;
    Uint32 *end = out + pixelsCount;

    __asm__ __volatile__ (
            "\n\t movd  (%0), %%mm0"
            "\n\t movd  (%1), %%mm1"
            "\n\t movd  (%2), %%mm2"
            "\n\t pxor       %%mm3, %%mm3"
            "\n\t punpcklbw  %%mm3, %%mm1"
            "\n\t punpcklbw  %%mm3, %%mm2"
            "\n\t psubw      %%mm2, %%mm1"
            "\n\t pmulhw     %%mm0, %%mm1"
            "\n\t paddw      %%mm2, %%mm1"
            "\n\t packuswb   %%mm3, %%mm1"
    : : "r" (alpha), "r" (A), "r" (B), "r" (out), "r" (end)
    );
    __asm__("emms" : : );
}

컴파일 할 때 Error: (%dl) is not a valid base/index expression어셈블러의 첫 번째 줄에 관한 메시지가 표시 됩니다. 나는 때문에 용의자 alpha입니다 Uint8, 내가 캐스팅 시도하지만 내가 세그먼트 오류를 얻을. 예에서 그들은 4 16-b zero-padding α나에게 명확하지 않은 것에 대해 이야기하고 있습니다.

Fuz

MM reg에 복사하기 전에 alpha스칼라 곱하기를 사용하여 64 비트로 브로드 캐스트 수 있습니다 0x0001000100010001ULL. 또 다른 옵션은에서 8 비트 정수를 32 비트로 0 확장 movd한 다음 pshufw복제하는 것입니다.

당신의 asm에도 다양한 안전 문제가있었습니다.

#include <SDL/SDL.h>
#include <stdint.h>

void fade_mmx(SDL_Surface* im1,SDL_Surface* im2,Uint8 alpha, SDL_Surface* imOut)
{
    int pixelsCount = imOut->w * im1->h;

    Uint32 *A = (Uint32*) im1->pixels;
    Uint32 *B = (Uint32*) im2->pixels;
    Uint32 *out = (Uint32*) imOut->pixels;
    Uint32 *end = out + pixelsCount;

    Uint64 alphas = (Uint64)alpha * 0x0001000100010001ULL;

    __asm__ __volatile__ (
            "\n\t movd  %0, %%mm0"
            "\n\t movd  %1, %%mm1"
            "\n\t movd  %2, %%mm2"
            "\n\t pxor       %%mm3, %%mm3"
            "\n\t punpcklbw  %%mm3, %%mm1"
            "\n\t punpcklbw  %%mm3, %%mm2"
            "\n\t psubw      %%mm2, %%mm1"
            "\n\t pmulhw     %%mm0, %%mm1"
            "\n\t paddw      %%mm2, %%mm1"
            "\n\t packuswb   %%mm3, %%mm1"
    : // you're probably going to want an "=m"(*something) memory output here
    : "r" (alphas), "m" (*A), "m" (*B), "r" (out), "r" (end)
    : "mm0", "mm1", "mm2", "mm3");
    __asm__("emms" : : );
}

volatile컴파일러가 "memory"클로버에 의존하는 대신 모든 입력과 출력에 대해 알고 있는 경우 asm 문이 필요하지 않습니다 . (여기처럼 출력이없고 입력 피연산자 인 레지스터와 메모리 만 읽습니다.)

32 비트 코드의 경우, 교체 "r"(alphas)와 함께 "m"(alphas). 또는 "rm"(alphas)컴파일러가 선택하도록 사용 하십시오. (그러나 32 비트의 경우 컴파일러가 64 비트 곱셈 결과를 2 개의 32 비트 반으로 저장하도록 만드는 대신 pshufw를 사용하는 것이 더 낫습니다. 그런 다음 movq로 다시로드 할 때 저장 전달 지연이 발생합니다. Intrinsics는 결정을 내릴 수 있습니다. _mm_set1_epi8(alpha)루프 밖에서 한 번 수행 하는 컴파일러 ).

또한 필요한 clobber 목록을 추가하고 역 참조하는 포인터를 포함하는 레지스터 피연산자를 역 참조하는 메모리를 참조하는 메모리 피연산자로 대체하여 gcc가 액세스하는 메모리에 대해 추론 할 수 있도록했습니다.

이러한 문제를 해결하지 않으면 gcc가 불행해질 것이며 코드의 동작이 정의되지 않고 신비스럽고 디버깅하기 어려운 방식으로 실패 할 수 있습니다. 수행중인 작업을 정확히 이해하지 않는 한 인라인 어셈블리를 사용하지 마십시오. 더 안전하고 잠재적으로 더 효율적인 대안으로 내장 함수를 사용하는 것을 고려하십시오. ( https://gcc.gnu.org/wiki/DontUseInlineAsm ).

__m128i벡터가있는 SSE2를 사용하면 pack0으로 패킹 하여 처리량의 절반을 낭비하는 2 개 또는 1 개가 아니라 한 번에 4 픽셀을 쉽게 처리 할 수 있습니다. (이에 대한 설정 punpckhbw을 보완하는 punpcklbw사용 ). MMX는 너무 구식이어서 최신 CPU는 동일한 128 비트 SSE2 XMM 명령어보다 일부 명령어의 MMX 버전에 대한 처리량이 낮습니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

Uint8 to mm0 register

분류에서Dev

MATLAB uint8 스파 스

분류에서Dev

uint8을 uint8 []로 캐스트

분류에서Dev

uint8을 uint32로 캐스팅

분류에서Dev

이미지 데이터 유형을 uint16에서 uint8로 변환

분류에서Dev

데이터를 UnsafePointer <UInt8>로 변환하는 방법?

분류에서Dev

{(Int)}는 UInt8과 동일하지 않습니다.

분류에서Dev

[UInt8] 변환 중? IO의 신속한 이미지

분류에서Dev

uint8 배열을 이미지로 변환

분류에서Dev

입력을위한 Caffe Python Layer, 데이터 유형을 uint8로 설정

분류에서Dev

UInt8 (또는 유사한 유형)을 Int로 변환하면 UInt8의 목적에 맞지 않습니까?

분류에서Dev

Numpy ndarray of dtype (uint8)을 OpenCV 판독 가능 이미지로 변환

분류에서Dev

Matlab 불일치 이미지를 단 정밀도에서 uint8로 변환

분류에서Dev

imshow를 사용할 때 uint8과 이중 이미지의 차이점

분류에서Dev

uint8을 부동으로 캐스팅 한 셰이더 및 uint로 다시 해석

분류에서Dev

uint8 *을 uint32 *로 캐스팅하는 방법은 무엇입니까?

분류에서Dev

인덱스 / 데이터 마스킹에서 최상의 데이터 가져 오기 / 설정 uint8

분류에서Dev

래스터 dtype을 uint8에서 float32로 변환하는 방법은 무엇입니까?

분류에서Dev

uint8의 중복 캐스트가 GCC 4.8.1에서 작동하지 않습니다.

분류에서Dev

Tensor ( "decode_jpeg : 0", shape = (?,?, 1), dtype = uint8)에서 0은 무엇을 의미합니까?

분류에서Dev

'UnsafePointer <UInt8>'을 초기화하면 댕글 링 포인터가 발생합니다.

분류에서Dev

런타임 오버 헤드가없는 문자열 리터럴에서 CChar 또는 UInt8 초기화 (Swift)

분류에서Dev

Kotlin에서 UNIX 타임 스탬프를 UInt8 배열로 변환하는 방법은 무엇입니까?

분류에서Dev

문자열을 UnsafeMutablePointer <UInt8>로 변환하는 방법은 무엇입니까? 스위프트 3

분류에서Dev

비 Objective-C 포인터 유형 'const UInt8 *'(일명 'const unsigned char *')을 'NSData *'로 캐스트하는 것은 ARC에서 허용되지 않습니다.

분류에서Dev

Objective-c는 서명되지 않은 문자의 UInt8 배열을 디코딩합니다.

분류에서Dev

Swift 사전에 [UInt8]을 값으로 넣어도 작동하지 않습니다.

분류에서Dev

Swift에서 [UInt32]-> [UInt8]-> [[UInt8]] 변환

분류에서Dev

Swift 인코딩 UInt8

Related 관련 기사

  1. 1

    Uint8 to mm0 register

  2. 2

    MATLAB uint8 스파 스

  3. 3

    uint8을 uint8 []로 캐스트

  4. 4

    uint8을 uint32로 캐스팅

  5. 5

    이미지 데이터 유형을 uint16에서 uint8로 변환

  6. 6

    데이터를 UnsafePointer <UInt8>로 변환하는 방법?

  7. 7

    {(Int)}는 UInt8과 동일하지 않습니다.

  8. 8

    [UInt8] 변환 중? IO의 신속한 이미지

  9. 9

    uint8 배열을 이미지로 변환

  10. 10

    입력을위한 Caffe Python Layer, 데이터 유형을 uint8로 설정

  11. 11

    UInt8 (또는 유사한 유형)을 Int로 변환하면 UInt8의 목적에 맞지 않습니까?

  12. 12

    Numpy ndarray of dtype (uint8)을 OpenCV 판독 가능 이미지로 변환

  13. 13

    Matlab 불일치 이미지를 단 정밀도에서 uint8로 변환

  14. 14

    imshow를 사용할 때 uint8과 이중 이미지의 차이점

  15. 15

    uint8을 부동으로 캐스팅 한 셰이더 및 uint로 다시 해석

  16. 16

    uint8 *을 uint32 *로 캐스팅하는 방법은 무엇입니까?

  17. 17

    인덱스 / 데이터 마스킹에서 최상의 데이터 가져 오기 / 설정 uint8

  18. 18

    래스터 dtype을 uint8에서 float32로 변환하는 방법은 무엇입니까?

  19. 19

    uint8의 중복 캐스트가 GCC 4.8.1에서 작동하지 않습니다.

  20. 20

    Tensor ( "decode_jpeg : 0", shape = (?,?, 1), dtype = uint8)에서 0은 무엇을 의미합니까?

  21. 21

    'UnsafePointer <UInt8>'을 초기화하면 댕글 링 포인터가 발생합니다.

  22. 22

    런타임 오버 헤드가없는 문자열 리터럴에서 CChar 또는 UInt8 초기화 (Swift)

  23. 23

    Kotlin에서 UNIX 타임 스탬프를 UInt8 배열로 변환하는 방법은 무엇입니까?

  24. 24

    문자열을 UnsafeMutablePointer <UInt8>로 변환하는 방법은 무엇입니까? 스위프트 3

  25. 25

    비 Objective-C 포인터 유형 'const UInt8 *'(일명 'const unsigned char *')을 'NSData *'로 캐스트하는 것은 ARC에서 허용되지 않습니다.

  26. 26

    Objective-c는 서명되지 않은 문자의 UInt8 배열을 디코딩합니다.

  27. 27

    Swift 사전에 [UInt8]을 값으로 넣어도 작동하지 않습니다.

  28. 28

    Swift에서 [UInt32]-> [UInt8]-> [[UInt8]] 변환

  29. 29

    Swift 인코딩 UInt8

뜨겁다태그

보관