是否保证对于static_cast<int>(std::sqrt(x * x)) == x所有正 x 且 x*x 不会溢出?
如果不是,我将如何稳健地计算这些数字的平方根?
在 Rust 中,假设我有一个枚举,我想根据它的变体和一些涉及它的值的测试做一些有条件的事情。我很难找到写这个的好方法。
例如,假设我有一个枚举来表示农场动物,变体给出了它们的物种,而值给出了一些其他属性,例如它们的重量。
enum Animal {
Horse(i32),
Cow(i32, i32),
Sheep,
// and so on
}
Run Code Online (Sandbox Code Playgroud)
我想要一个喂养动物的功能。大多数动物都吃干草,但体重低于 700 公斤的马却吃胡萝卜。
直觉上我想写
fn feed(animal: Animal) {
if let Animal::Horse(weight) = animal && weight < 700 { // ferris_is_confused.png
// feed carrots
} else {
// feed hay
}
}
Run Code Online (Sandbox Code Playgroud)
但我得到编译错误“let这个位置的表达式是实验性的”和“预期的表达式,找到的语句(let)”。
我可以写
fn feed(animal: Animal) {
if let Animal::Horse(weight) = animal {
if weight < 700 {
// feed carrots
} else {
// feed hay
}
} else …Run Code Online (Sandbox Code Playgroud) 如何使用 AVX2 向量化这个 C 函数?
static void propogate_neuron(const short a, const int8_t *b, int *c) {
for (int i = 0; i < 32; ++i){
c[i] += a * b[i];
}
}
Run Code Online (Sandbox Code Playgroud) vaddhn_high_s16arm64有内在的。
此内在函数的官方 ARM 文档在此处。但是,给出的描述和伪代码都让我感到困惑。
任何人都可以使用实用的 C/C++ 代码来解释它的vaddhn_high_s16作用吗?
例如,假设所有数据类型都已定义,并且vmulq_f32可以使用以下实现解释内在类型:
float32x4_t vmulq_f32(float32x4_t a, float32x4_t b)
{
float32x4_t r;
for (int i=0; i<4; i++)
{
r[i] = a[i] * b[i];
}
return r;
}
Run Code Online (Sandbox Code Playgroud) 这是源代码。
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
void win()
{
printf("code flow successfully changed\n");
}
int main(int argc, char **argv)
{
char buffer[64];
gets(buffer);
}
Run Code Online (Sandbox Code Playgroud)
main 的汇编代码
0x0000000000400604 <+0>: stp x29, x30, [sp, #-96]!
0x0000000000400608 <+4>: mov x29, sp
0x000000000040060c <+8>: str w0, [sp, #28]
0x0000000000400610 <+12>: str x1, [sp, #16]
0x0000000000400614 <+16>: add x0, sp, #0x20
0x0000000000400618 <+20>: bl 0x4004d0 <gets@plt>
0x000000000040061c <+24>: mov w0, #0x0 // #0
0x0000000000400620 <+28>: ldp x29, x30, [sp], #96
0x0000000000400624 <+32>: …Run Code Online (Sandbox Code Playgroud) 我正在 ARM64 M1 Pro 笔记本电脑上使用 clang 13.1.6 和 MacOS Monterey 12.5 进行汇编编写。
如果我尝试在以标签地址作为其值的部分中使用.dword/ ,我的程序会在启动时崩溃,并带有..xword.textbus error
最小可重现示例:
.text
.balign 4
.global _main
_main:
// accepted method to load from static address
adrp x1, vector@GOTPAGE
ldr x1, [x1, #vector@GOTPAGEOFF]
// now x1 contains the address of vector
ldr x2, [x1]
// now x2 should contain the address of dest
br x2
dest:
mov x0, #0
ret
vector:
.xword dest
Run Code Online (Sandbox Code Playgroud)
使用 进行汇编和链接时不会出现错误或警告cc reloc.s -o reloc,但在运行时会立即出现总线错误,显然是在到达我的实际代码之前。回溯lldb …
我在zircon kernel start.S中找到了这行汇编代码
str x0, [tmp, #:lo12:zbi_paddr]
Run Code Online (Sandbox Code Playgroud)
对于ARM64。我还发现zbi_paddrC++ 中定义了:
extern paddr_t zbi_paddr;
Run Code Online (Sandbox Code Playgroud)
所以我开始研究这#:lo12:意味着什么。
我发现/sf/answers/2702611691/看起来像是一个很好的解释,但它没有解释非常基本的内容:什么是重新分配以及为什么需要一些东西。
我猜想,由于在 C++ 代码中zbi_paddrr定义并使用,由于在地址从 0 开始的目标文件上生成,因此链接过程必须将其中的所有地址重新分配到最终可执行文件中的地址。start.Sstart.Sstart.o
为了跟踪需要重新分配的符号,ELF 存储这些结构,如答案中所述:
typedef struct
{
Elf64_Addr r_offset; /* Address of reference */
Elf64_Xword r_info; /* Symbol index and type of relocation */
} Elf64_Rel;
typedef struct
{
Elf64_Addr r_offset; /* Address of reference */
Elf64_Xword r_info; /* Symbol index and type of relocation */
Elf64_Sxword r_addend; /* Constant part …Run Code Online (Sandbox Code Playgroud) 下面是 AVX2 中矩阵乘法的实现。我使用的机器仅支持 AVX,因此我尝试使用 AVX 实现相同的配置。
然而,我很难真正理解差异是什么,以及需要改变什么!此实现中哪些内容是 AVX2 特有的,无法与只能处理 AVX 的机器一起使用?
这是 AVX 和 AVX2 所有命令的链接 https://software.intel.com/sites/landingpage/IntrinsicsGuide/#techs=AVX
感谢您的任何见解!
for (uint64_t i = 0; i < M; i++)
{
for (uint64_t j = 0; j < N; j++)
{
__m256 X = _mm256_setzero_ps();
for (uint64_t k = 0; k < L; k+= 8) {
const __m256 AV = _mm256_load_ps(A+i*L+k);
const __m256 BV = _mm256_load_ps(B+j*L+k);
X = _mm256_fmadd_ps(AV,BV,X);
}
C[i*N+j] = hsum_avx(X);
}
}
Run Code Online (Sandbox Code Playgroud) 参照在代码片段cppreference.com这我下面粘贴为什么整数b,并c在相同的内存位置分配:
struct S {
char a; // memory location #1
int b : 5; // memory location #2
int c : 11, // memory location #2 (continued)
: 0,
d : 8; // memory location #3
struct {
int ee : 8; // memory location #4
} e;
} obj; // The object 'obj' consists of 4 separate memory locations
Run Code Online (Sandbox Code Playgroud)
我的理解是,例如,在1字节= 8位的系统中,变量a将占用1字节。然后b需要说4个字节。如果同时b并c在相同的内存位置这将填补8个字节去,这是否意味着8个char变量可以在相同的内存位置中持续地分配呢?
另外,程序如何知道要访问的位置b …
GCC 的最新版本(包括版本 12)实现了过程间分析,该分析会严重损坏 ARM/Thumb 上系统调用存根的以下(仅限 GCC)代码。
typedef struct { int sender; int arg; } message;
#define syscall(op) asm volatile ("svc %0" :: "i"(op))
#define SYS_SEND 9
#define NOINLINE __attribute((noinline))
void NOINLINE send(int dest, int type, message *msg)
{
syscall(SYS_SEND);
}
void send_int(int d, int t, int v)
{
message msg;
msg.arg = v;
send(d, t, &msg);
}
Run Code Online (Sandbox Code Playgroud)
目的是操作系统的陷阱处理程序将send通过访问参数寄存器的保存值来找到三个参数r0——r2在陷阱的异常帧中。问题显然是优化器在查看 的主体时send认为其消息参数的字段未被使用。msg.arg因此,主体中对 的赋值send_int被删除。这是通过编译上述源代码揭示的
arm-none-eabi-gcc -mcpu=cortex-m0 -mthumb -O -g -Wall -ffreestanding -c …Run Code Online (Sandbox Code Playgroud)