相关疑难解决方法(0)

为什么Java API使用int而不是short或byte?

为什么Java API会使用int,何时short甚至byte是足够的?

示例:DAY_OF_WEEK类中的字段Calendar使用int.

如果差异太小,那么为什么存在这些数据类型(short,int)?

java optimization types java-api

134
推荐指数
5
解决办法
1万
查看次数

什么是数据对齐?当在C中进行类型转换指针时,为什么以及何时应该担心?

我找不到一个体面的文档来解释对齐系统如何工作以及为什么某些类型比其他类型更严格一致.

c c++ memory

23
推荐指数
3
解决办法
5381
查看次数

对齐与未对齐的x86 SIMD指令之间的选择

通常有两种类型的SIMD指令:

A.使用对齐的内存地址的那些,如果地址未在操作数大小边界上对齐,则会引发一般保护(#GP)异常:

movaps  xmm0, xmmword ptr [rax]
vmovaps ymm0, ymmword ptr [rax]
vmovaps zmm0, zmmword ptr [rax]
Run Code Online (Sandbox Code Playgroud)

B.以及使用未对齐内存地址的那些,不会引发此类异常:

movups  xmm0, xmmword ptr [rax]
vmovups ymm0, ymmword ptr [rax]
vmovups zmm0, zmmword ptr [rax]
Run Code Online (Sandbox Code Playgroud)

但是我只是好奇,为什么我要用脚射击自己并使用第一组的对齐记忆指令呢?

x86 sse simd avx avx512

8
推荐指数
2
解决办法
755
查看次数

为什么std :: atomic <T> :: is_lock_free()和constexpr一样不是静态的?

谁能告诉我std :: atomic :: is_lock_free()是否像constexpr一样不是静态的?使它为非静态和/或为非constexpr对我来说没有意义。

c++ multithreading std lock-free stdatomic

8
推荐指数
2
解决办法
153
查看次数

警告:获取“结构详细信息”的打包成员的地址可能会导致未对齐的指针值 [-Waddress-of-packed-member]

       struct details_state {
               struct details_status D1;
               struct details_status D2;
       };

       struct details {
           struct details_state details_states[2];
       } __attribute__((packed));


        struct details *p;

        void print_details_status(struct details_status *s)

        print_details_status(&(p->details_states[i].D1));
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)

警告:获取“结构详细信息”的打包成员的地址可能会导致未对齐的指针值 [-Waddress-of-packed-member]

GCC 在 >9 版本中给出此警告。如何在不使用 [-Wno-address-of-packed-member] 的情况下摆脱此警告

c struct gcc-warning gcc9 gcc11

6
推荐指数
1
解决办法
1万
查看次数

如何在x86_64上准确地对准未对齐的访问速度

答案中,我已经声明未对齐访问的速度与对齐访问的速度几乎相同(在x86/x86_64上).我没有任何数字来支持这个陈述,所以我已经为它创建了一个基准.

你看到这个基准测试有什么缺陷吗?你可以改进它(我的意思是,增加GB /秒,所以它更好地反映了真相)?

#include <sys/time.h>
#include <stdio.h>

template <int N>
__attribute__((noinline))
void loop32(const char *v) {
    for (int i=0; i<N; i+=160) {
        __asm__ ("mov     (%0), %%eax" : : "r"(v) :"eax");
        __asm__ ("mov 0x04(%0), %%eax" : : "r"(v) :"eax");
        __asm__ ("mov 0x08(%0), %%eax" : : "r"(v) :"eax");
        __asm__ ("mov 0x0c(%0), %%eax" : : "r"(v) :"eax");
        __asm__ ("mov 0x10(%0), %%eax" : : "r"(v) :"eax");
        __asm__ ("mov 0x14(%0), %%eax" : : "r"(v) :"eax");
        __asm__ ("mov 0x18(%0), %%eax" : : "r"(v) :"eax"); …
Run Code Online (Sandbox Code Playgroud)

performance benchmarking x86 x86-64 inline-assembly

5
推荐指数
1
解决办法
881
查看次数

在内存中交换未对齐的 64 位值的字节的最快方法是什么?

我在内存中有大量 64 位值。不幸的是,它们可能不会与 64 位地址对齐。我的目标是改变所有这些值的字节序,即交换/反转它们的字节。

我知道bswap交换 32 位或 64 位寄存器字节的指令。但是因为它需要一个寄存器参数,所以我不能将它传递给我的内存地址。当然我可以先将内存加载到寄存器中,然后交换,然后写回:

mov rax, qword [rsi]
bswap rax
mov qword [rsi], rax
Run Code Online (Sandbox Code Playgroud)

但这是否正确,因为地址可能未对齐?

另一种可能性是手动进行交换:

mov al, byte [rsi + 0]
mov bl, byte [rsi + 7]
mov byte [rsi + 0], bl
mov byte [rsi + 7], al

mov al, byte [rsi + 1]
mov bl, byte [rsi + 6]
mov byte [rsi + 1], bl
mov byte [rsi + 6], al

mov al, byte [rsi + 2]
mov bl, …
Run Code Online (Sandbox Code Playgroud)

performance assembly x86-64 endianness micro-optimization

5
推荐指数
1
解决办法
510
查看次数

GCC生成的ARM和x86汇编代码的差异

让我们用一个简单的C代码来设置寄存器:

int main()
{
    int *a = (int*)111111;
    *a = 0x1000;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我使用1级优化编译ARM(arm-none-eabi-gcc)代码时,汇编代码如下:

mov     r2, #4096
mov     r3, #110592
str     r2, [r3, #519]
mov     r0, #0
bx      lr
Run Code Online (Sandbox Code Playgroud)

看起来地址111111被解析为最接近的4K边界(110592)并移动到r3,然后通过将519添加到110592(= 111111)来存储值4096(0x1000).为什么会这样?

在x86中,程序集很简单:

movl    $4096, 111111
movl    $0, %eax
ret
Run Code Online (Sandbox Code Playgroud)

compiler-construction x86 assembly gcc arm

2
推荐指数
1
解决办法
1810
查看次数

理解 JIT 对 for 循环的重写

我有以下Java代码(所有数组在我们调用“arrays”之前都已初始化,并且所有数组的大小均为“arraySize”)

int arraySize = 64;

float[] a;
float[] b;
float[] result;

public void arrays() {
    for (int i = 0; i < arraySize; i++) {
        result[i] = ((a[i] * b[i] + b[i] - b[i]) / b[i]) +
                     a[i] + a[i] + a[i] + a[i];
    }
}
Run Code Online (Sandbox Code Playgroud)

JIT 的输出是:

# {method} {0x00000001034751a8} 'arrays' '()V' in 'main/ComplexExpression'
#           [sp+0x30]  (sp of caller)
[Entry Point]
0x000000010c4c55a0: mov 0x8(%rsi),%r10d
0x000000010c4c55a4: movabs $0x800000000,%r11
0x000000010c4c55ae: add %r11,%r10
0x000000010c4c55b1: cmp %r10,%rax
0x000000010c4c55b4: jne 0x000000010c44b780  ;   {runtime_call ic_miss_stub} …
Run Code Online (Sandbox Code Playgroud)

java assembly jit x86-64 auto-vectorization

1
推荐指数
1
解决办法
181
查看次数

SIMD (avx) 处理如何工作?例如,如果我想要 10 个 32 位浮点数,如何放入 256 位 avx 向量?

我正在学习 C avx 内在函数,我想知道它是如何工作的。

我很熟悉我可以做这样的事情:

__m256 evens = _mm256_set_ps(2.0, 4.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0);
Run Code Online (Sandbox Code Playgroud)

这里我存储 8 个 32 位浮点数。所以这是 256 位。

但是假设我正在编写一个线性代数库。然后我如何处理任意数量的向量;例如,如何将 10 个 32 位浮点数放入 avx 向量中?

如果您能提供一些例子,我将非常感激

c simd avx

-1
推荐指数
1
解决办法
161
查看次数