Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何解决二维数组中具有内存输出操作数的SIMD内联asm的lvalue问题?

如何解决二维数组中具有内存输出操作数的SIMD内联asm的lvalue问题?
EN

Stack Overflow用户
提问于 2021-11-18 10:50:35
回答 1查看 243关注 0票数 1

我正在尝试编写一个函数,它将使用ymm寄存器填充浮点矩阵中的零。

不久之后,我编写了这个函数:

代码语言:javascript
运行
AI代码解释
复制
void fillMatrixByZeros(float matrix[N][N]){
    for (int k = 0; k < N; k += 8){
        for (int i = 0; i < N; ++i){
            asm volatile (
                "vxorps %%ymm0, %%ymm0, %%ymm0;"
                "vmovups %%ymm0, (%0)"
                : "=m"(matrix[i] + k)
                : 
                : "%ymm0", "memory"
            );
        }
    }
}

我试着编译我的全部代码,并得到了以下错误:

代码语言:javascript
运行
AI代码解释
复制
prog.cpp: In functionvoid fillMatrixByZeros(float (*)[16]):
prog.cpp:35:8: error: lvalue required in asm statement
   35 |       );
      |        ^
prog.cpp:35:8: error: invalid lvalue in asm output 0

我得出了一个结论:matrix[i]+k是一个rvalue或类似的值,所以不能在那里使用它。

在谷歌搜索之后,我想出了两个解决方案:

First

代码语言:javascript
运行
AI代码解释
复制
void fillMatrixByZeros(float matrix[N][N]){
    for (int k = 0; k < N; k += 8){
        for (int i = 0; i < N; ++i){
            asm volatile (
                "vxorps %%ymm0, %%ymm0, %%ymm0;"
                "vmovups %%ymm0, (%0)"
                : 
                : "r"(matrix[i] + k)
                : "%ymm0", "memory"
            );
        }
    }
}

第二

代码语言:javascript
运行
AI代码解释
复制
void fillMatrixByZeros(float matrix[N][N]){
    long long int matrixPointer;
    for (int k = 0; k < N; k += 8){
        for (int i = 0; i < N; ++i){
            asm volatile (
                "vxorps %%ymm0, %%ymm0, %%ymm0;"
                "vmovups %%ymm0, (%0)"
                : "=r"(matrixPointer)
                : "0"(matrix[i] + k)
                : "%ymm0", "memory"
            );
        }
    }
}

这些功能正常工作。我想知道为什么。

为什么在第一个函数中没有任何值问题?第二个函数是怎么回事?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-18 12:35:47

您不能分配给matrix[i] + k,所以它不是一个lvalue。m约束需要内存中的对象,而不是其地址。因此,要解决这个问题,请提供要分配给的对象,而不是它的地址:

代码语言:javascript
运行
AI代码解释
复制
void fillMatrixByZeros(float matrix[N][N]){
    for (int k = 0; k < N; k += 8){
        for (int i = 0; i < N; ++i){
            asm volatile (
                "vxorps %%ymm0, %%ymm0, %%ymm0;"
                "vmovups %%ymm0, %0"
                : "=m"(matrix[i][k])
                : 
                : "%ymm0", "memory"
            );
        }
    }
}

这是在内联程序集语句中访问内存中的对象的正确方法。

使用带有操作数地址的r约束的解决方案,然后也执行显式取消引用工作。但它们可能效率较低,因为它们阻止编译器使用其他寻址模式,如SIB寻址模式。相反,它必须首先在登记簿上显示地址。

你的最后一个例子有点傻。它使用耦合的asm操作数在传递给内联程序集语句之前本质上执行matrixPointer = matrix[i] + k。这是一种非常迂回的方法,根本不需要。

尽管如此,为了进一步提高效率,您应该将ymm0的清除从循环中提升。也许是这样的?

代码语言:javascript
运行
AI代码解释
复制
#include <immintrin.h>

#define N 1000

void fillMatrixByZeros(float matrix[N][N]){
    for (int k = 0; k < N; k += 8){
        for (int i = 0; i < N; ++i){
            asm volatile (
                "vmovups %1, %0"
                : "=m"(matrix[i][k])
                : "x"(_mm256_setzero_ps())
                : "memory"
            );
        }
    }
}

请注意,只调用memset可能会比手动内嵌程序集执行得更好。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70025215

复制
相关文章
Java二维数组的输出
(i)输出长度“最小长度为5”,所以当长度<=5时,所得为左对齐的长度为5的固定格式。 (ii)当长度>5时,完全输出,并且如输出结果第二行所示,会紧贴右边数据。
全栈程序员站长
2022/09/05
9630
PHP循环输出二维数组的数据
//下面是一个例子 $g_id = isset($_GET['id'])?$_GET['id']:'1';//定义变量$g_id,使用三元运算符是为了避免出现waring $p_id = ($g_id
Yiiven
2022/12/15
2.1K0
内存中的数组
1、数组是一种引用数据类型,数组引用变量只是一个引用,数组元素和数组变量在内存里是分开存放的。 2、引用变量是访问真实对象的根本方式,如果程序中要访问数组对象本身,则只能通过这个数组的引用变量来访问它。 3、实际的数组对象被存储在堆内存中;如果引用该数组对象的数组引用变量是一个局部变量,那么它被存储在栈内存中。
程序员云帆哥
2022/05/12
1.1K0
内存中的数组
二维数组的DP问题
问题:平面上有N*M个格子,每个格子中放着一定数量的苹果。你从左上角的格子开始,每一步只能向下走或是向右走,每次走到一个格子上就把格子里的苹果收集起来,这样下去,你最多能收集到多少个苹果
Meet相识
2018/09/12
7720
JNI:如何操作数组
这类函数可以把Java基本类型的数组转换到C/C++的数组,有两种处理方式,一是拷贝一份传回本地代码,另一个是把指向Java数组的指针直接传回到本地代码。处理完本地的数组后,通过Release<TYPE>ArrayElements来释放数组。
BUG弄潮儿
2022/03/08
4700
Numpy 如何操作数组
数组类型 Numpy类型 # --*--coding:utf-8--*-- from numpy import * """ 复数数组 """ a = array([1 + 1j, 2, 3, 4]) # 数组类型 print('type:', a.dtype) # 实部 print(a.real) # 虚部 print(a.imag) # 复共轭 print(a.conj()) """ 指定数组类型 """ a = array([1, 2, 4, 9, 10], dtype=float32) prin
村雨遥
2022/06/15
5830
Numpy 如何操作数组
java输出数组的方法_java怎样输出数组中的所有元素
调用Array.toString(a),返回一个包含数组元素的字符串,这些元素被放置在括号内,并用逗号分开
全栈程序员站长
2022/11/18
4.8K0
操作系统(4)实验0——准备知识、基本内联汇编、扩展内联汇编
建议在虚拟机中使用Ubuntu 16.04来做实验(其实用18或者更新的也行,但是我还是习惯16的Unity桌面)。
太阳影的社区
2021/10/15
7370
内联汇编很可怕吗?看完这篇文章,终结它!
在 Linux 代码中,经常可以看到在 C 代码中,嵌入部分汇编代码,这些代码要么是与硬件体系相关的,要么是对性能有关键影响的。
IOT物联网小镇
2021/05/13
2.4K0
内联汇编很可怕吗?看完这篇文章,终结它!
java——内存中的数组
2、arr=new int[5],这段代码执行完成后,系统会在堆内存中为该数组分配一块内存空间,并初始化值0,如下图所示:
说故事的五公子
2019/09/11
1.1K0
java——内存中的数组
thinkphp模板中数组的输出
$this->assign('design_img',$design_img); //thinkphp 一维数组输出 <foreach name="design_img" item="vo"> <input type="text" name="design_img[]" value="{$vo}" /> </foreach> //二维数组 <volist name="design_img" id="design_img"> {$design_img.name} </volist> //多维数
PM吃瓜
2019/08/12
2.4K0
Java数组在内存中是如何存放的
当一个对象使用关键字“new”创建时,会在堆上分配内存空间,然后返回对象的引用,这对数组来说也是一样的,因为数组也是一个对象;
田维常
2020/04/21
1.7K0
Java数组在内存中是如何存放的
C++二维数组 | 二维数组输出0-6
C++的二维数组是指具有两个下标的数组,有些数据要依赖于两个因素才能惟一地确定,因此才会引入二维数组。
小林C语言
2020/12/01
8270
C++二维数组 | 二维数组输出0-6
二维数组中的查找
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
用户3003813
2018/09/06
2K0
[剑指offer] 二维数组中的查找
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数
尾尾部落
2018/09/04
2.2K0
[剑指offer] 二维数组中的查找
二维数组中的查找
给定一个二维数组,其每一行从左到右递增排序,从上到下也是递增排序。给定一个数,判断这个数是否在该二维数组中。
崩天的勾玉
2021/12/20
1.6K0
二维数组中的查找
给定一个二维数组,其每一行从左到右递增排序,从上到下也是递增排序。给定一个数,判断这个数是否在该二维数组中。
MickyInvQ
2021/10/26
1.8K0
二维数组中的查找
时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M 热度指数:1946753
后端码匠
2021/08/18
1.8K0
java中输出数组内容的函数,并将数组内容作为参数_数组的逆序输出
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/11/08
2.9K0
PHP 中操作数组的知识点
数组的赋值: PHP中的数组既可以做数组,也可以做键值对字典,且不存在限制,非常灵活.
王瑞MVP
2022/12/28
2.4K0

相似问题

内联asm:“`in”的操作数类型错配

35

内联asm和c数组问题

15

如何获得llvm内联asm操作数类型?

13

aarch64-gcc simd内联asm,结果总是0。

13

内联asm jmp --“指令操作数无效”

319
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档