를 추가 말하는 유지 (" "r"
->: "r"
), 문제는 일치하지 않는 매개 변수입니다 . -S에서 출력을 보면
: 이것은 당신이 기대하는 것입니다, cnt
이후
add rax, r8b
은 size_t로하고 bytes[i]
는 바이트이다. 추가를하면 크기가 동일해야합니다.
또한 인라인 asm 대신 builtins를 사용할 것을 제안 할 수 있습니까? 이 문제는 (다른 많은 것들도 마찬가지입니다) 피합니다.
먼저 레지스터에을 저장하지 않고 popcnt에서 결과를 추가 할 수있는 방법이 있습니까?
음. 그것은 사실 전혀 다른 질문입니다. 당신이 물어 본 오류는 단일 add
명령에서 바이트와 size_t를 섞어서 발생했습니다. 그것은 수행하여 해결할 수 있습니다 : 나는 (? 내 카르마 포인트를 획득하는 방법) 새로운 질문을 계속 추가하는 것이 좋습니다 안
__asm__(
"popcnt %0, %0 \n\t"
"add %0, %1 \n\t"
: "+r" (cnt)
: "r" ((size_t)bytes[i]));
하지만, 해당 웹 사이트에서 찾고, 코드는 그는 덤비는 것 같다
uint32_t builtin_popcnt_unrolled_errata(const uint64_t* buf, int len) {
assert(len % 4 == 0);
int cnt[4];
for (int i = 0; i < 4; ++i) {
cnt[i] = 0;
}
for (int i = 0; i < len; i+=4) {
cnt[0] += __builtin_popcountll(buf[i]);
cnt[1] += __builtin_popcountll(buf[i+1]);
cnt[2] += __builtin_popcountll(buf[i+2]);
cnt[3] += __builtin_popcountll(buf[i+3]);
}
return cnt[0] + cnt[1] + cnt[2] + cnt[3];
}
그는 popcnt의 'false dependency'문제를 피하기 위해 명시 적으로 cnt [x]를 사용합니다.
, GCC 6.1을 사용하고 -m64 -O3 -march=native -mtune=native
컴파일 I 출력으로 이것을보고 있어요 "레지스터에 떨어져 저장"
.L14:
popcnt r11, QWORD PTR [rcx]
add rcx, 32
add edx, r11d
popcnt r11, QWORD PTR -24[rcx]
add eax, r11d
popcnt r11, QWORD PTR -16[rcx]
add r10d, r11d
popcnt r11, QWORD PTR -8[rcx]
add r9d, r11d
cmp rcx, r8
jne .L14
당신이 언급하는?
내가 builtins로 시작했지만 더 빠른 것을 원했습니다. popcnt의 결과를 레지스터에 저장하지 않고 추가 할 수있는 방법이 있습니까? https://danluu.com/assembly-intrinsics/ –
답변을 주셔서 감사합니다. 나는 단지 블로그 포스트가 말하려고했던 것과 혼동되어 있었음에 틀림 없다. 여기에 당신의 업장 지점이 있습니다 :) –
블로그에는 날짜가 없지만 4.8.2를 사용하여 작성했습니다. 오래 전 이었으므로 상황이 바뀔 수도 있습니다. 이것은 인라인 대신 빌트인을 사용하는 것이 권장되는 또 다른 이유입니다. 내장 함수는 시간이 지남에 따라 향상 될 수 있지만 인라인으로 작성하면 작성한 내용 만 얻을 수 있습니다. BTW, 성능이 중요하다면, 64 비트 popcnt를 사용하는 것은 아마도 8 비트 반복보다 빠릅니다. len을 확인하고 이상한 크기를 처리해야하지만 시간을두고 시도해야합니다. –