AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / user-916672

Kevin Meier's questions

Martin Hope
Kevin Meier
Asked: 2024-12-22 05:36:36 +0800 CST

AVX2 / gcc:通过使用不同的寄存器来提高 CPU 级并行性

  • 7

我有这个代码:

__attribute__((target("avx2")))
size_t lower_than_16(const uint64_t values[16], uint64_t x)
{
    __m256i vx = _mm256_set1_epi64x(x);
    __m256i vvals1 = _mm256_loadu_si256((__m256i*)&values[0]);
    __m256i vvals2 = _mm256_loadu_si256((__m256i*)&values[4]);
    __m256i vvals3 = _mm256_loadu_si256((__m256i*)&values[8]);
    __m256i vvals4 = _mm256_loadu_si256((__m256i*)&values[12]);
    __m256i vcmp1  = _mm256_cmpgt_epi64(vvals1, vx);
    __m256i vcmp2  = _mm256_cmpgt_epi64(vvals2, vx);
    __m256i vcmp3  = _mm256_cmpgt_epi64(vvals3, vx);
    __m256i vcmp4  = _mm256_cmpgt_epi64(vvals4, vx);
    const int mask = (_mm256_movemask_pd((__m256d)vcmp1)) |
                    (_mm256_movemask_pd((__m256d)vcmp2) << 4) |
                    (_mm256_movemask_pd((__m256d)vcmp3) << 8) |
                    (_mm256_movemask_pd((__m256d)vcmp4) << 12);
    if (mask != 0xFFFF) {
        // found
        return __builtin_ctz(~mask);
    }

    return 16;
}

基本上,给定一个包含 16 个元素的数组,我想找到第一个为真的元素的索引values[i] <= x。如果找不到元素,则返回 16。

这是使用 AVX2 实现的,我使用 gcc 作为编译器。汇编代码如下:

lower_than_16:
        vmovq   xmm2, rsi
        vmovdqu ymm1, YMMWORD PTR [rdi]
        vpbroadcastq    ymm0, xmm2
        vpcmpgtq        ymm1, ymm1, ymm0
        vmovmskpd       esi, ymm1
        vmovdqu ymm1, YMMWORD PTR [rdi+32]
        vpcmpgtq        ymm1, ymm1, ymm0
        vmovmskpd       eax, ymm1
        vmovdqu ymm1, YMMWORD PTR [rdi+64]
        sal     eax, 4
        vpcmpgtq        ymm1, ymm1, ymm0
        vmovmskpd       ecx, ymm1
        vmovdqu ymm1, YMMWORD PTR [rdi+96]
        sal     ecx, 8
        vpcmpgtq        ymm0, ymm1, ymm0
        or      eax, ecx
        or      eax, esi
        vmovmskpd       edx, ymm0
        sal     edx, 12
        or      eax, edx
        mov     edx, 16
        cmp     eax, 65535
        je      .L1
        not     eax
        xor     edx, edx
        rep bsf edx, eax
.L1:
        mov     rax, rdx
        vzeroupper
        ret

(可在此处查看: https: //godbolt.org/z/7eea39Gqv)

我看到gcc每次展开迭代都使用相同的寄存器。但是,如果每次展开迭代都使用不同的寄存器,效率会不会更高ymm,因为这样 CPU 就可以更轻松地并行执行这 4 个独立的比较?我知道 CPU 会进行一些寄存器重命名,但它是否足够智能,不会强制这些指令不并行执行?或者,如果使用不同的寄存器,会不会更容易/更高效?

多谢

gcc
  • 1 个回答
  • 28 Views
Martin Hope
Kevin Meier
Asked: 2024-01-09 21:37:48 +0800 CST

x64:并发写入布尔数组

  • 7

假设我在 C 中有一个这样的数组:

static volatile bool my_array[128] = {0};

最重要的是,我有 128 个线程,每个线程在完成时都会写入不同的索引。true

这会产生一些问题吗?在 x64 上写入单个字节不会影响周围的字节,对吗?

我只是问,因为我不确定CPU/内存控制器/等是否总是读取8(或4)字节,然后写入它们。这会产生一些奇怪的竞争条件。

多谢

c
  • 1 个回答
  • 80 Views
Martin Hope
Kevin Meier
Asked: 2023-09-03 17:41:03 +0800 CST

尝试对 char[16] 数组进行排序时出现编译器错误

  • 8

如何std::sort用于对固定大小的数组进行排序(例如typedef XXX char[16])?我尝试了一些方法,但似乎不起作用。例如我当前的代码如下所示:

#include <iostream>
#include <algorithm>
#include <cstring>

typedef char t_name[16];

bool compareNames(const t_name& name1, const t_name& name2) {
    return strcmp(name1, name2) < 0;
}

int main() {
    t_name names[] = {
        "bruno",
        "karl",
        "adrian",
        "yanick"
    };

    int numNames = sizeof(names) / sizeof(names[0]);

    std::sort(names, names + numNames, compareNames);

    for (int i = 0; i < numNames; i++) {
        std::cout << names[i] << std::endl;
    }

    return 0;
}

不幸的是,这段代码无法编译。可能是因为普通赋值不适用于数组类型。错误(不太可读)可以在这里看到: https ://godbolt.org/z/Ms54P7ozj

也许有人知道如何实现这一点?不幸的是,我无法控制要排序的数组类型,因此无法更改。

c++
  • 4 个回答
  • 107 Views

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    重新格式化数字,在固定位置插入分隔符

    • 6 个回答
  • Marko Smith

    为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会?

    • 2 个回答
  • Marko Smith

    VScode 自动卸载扩展的问题(Material 主题)

    • 2 个回答
  • Marko Smith

    Vue 3:创建时出错“预期标识符但发现‘导入’”[重复]

    • 1 个回答
  • Marko Smith

    具有指定基础类型但没有枚举器的“枚举类”的用途是什么?

    • 1 个回答
  • Marko Smith

    如何修复未手动导入的模块的 MODULE_NOT_FOUND 错误?

    • 6 个回答
  • Marko Smith

    `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它?

    • 3 个回答
  • Marko Smith

    在 C++ 中,一个不执行任何操作的空程序需要 204KB 的堆,但在 C 中则不需要

    • 1 个回答
  • Marko Smith

    PowerBI 目前与 BigQuery 不兼容:Simba 驱动程序与 Windows 更新有关

    • 2 个回答
  • Marko Smith

    AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String”

    • 1 个回答
  • Martin Hope
    Fantastic Mr Fox msvc std::vector 实现中仅不接受可复制类型 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant 使用 chrono 查找下一个工作日 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor 构造函数的成员初始化程序可以包含另一个成员的初始化吗? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský 为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul C++20 是否进行了更改,允许从已知绑定数组“type(&)[N]”转换为未知绑定数组“type(&)[]”? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann 为什么 {2,3,10} 和 {x,3,10} (x=2) 的顺序不同? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller 在 5.2 版中,bash 条件语句中的 [[ .. ]] 中的分号现在是可选的吗? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench 为什么双破折号 (--) 会导致此 MariaDB 子句评估为 true? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng 为什么 `dict(id=1, **{'id': 2})` 有时会引发 `KeyError: 'id'` 而不是 TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String” 2024-03-20 03:12:31 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve