cheerp 减小调用转换类型的开销的方式

简介: 这个文章主要描述在cheerp环境下, c++和javascript代码减小类型转换开销在cheerp,基本数据类型的C ++阵列如char,unsigned char,short,unsigned short,int,unsigned int,float和double由JavaScript键入相应类型的阵列的支持。

这个文章主要描述在cheerp环境下, c++和javascript代码减小类型转换开销

在cheerp,基本数据类型的C ++阵列如char,unsigned char,short,unsigned short,int,unsigned int,float和double由JavaScript键入相应类型的阵列的支持。

Cheerp提供了一些API来将C ++数组转换为底层的Typed Array对象。这对于将C ++数据直接传递给WebGL等浏览器API特别有用。

建议

在cheerp里如果对js侧公开一定的方法,请仔细处理转换程序, 应为在某个情况下,编译器并没有人聪明。
比如说我们都知道在c侧(经常需要) 拷贝内存, 有时候clang会把我们的代码交叉编译成赋值拷贝,这个就会有问题了, 如果我们在使用智能指针的时候,传递了一个超大的字节数组给cheerp,赋值拷贝的性能开销会很大。 我们在使用的时候一定要思考我们的最终目标是什么。如果是小块的内存拷贝,那么赋值的速度要优于大块的memcpy方法, 如果数量级比较大,比如说操作视频文件解密, 我们必须使用cheerp的特有转换API来告诉编译器,不要这样做。

转换API

TypedArrayForPointerType
template < typename Tstruct TypedArrayForPointerType ;

模板助手,为特定的C数据类型获取相应的Typed Array类型。所需类型可用作::type成员。例如

TypedArrayForPointerType < unsigned short > :: type
以下映射适用:

char - > Int8Array
unsigned char - > Uint8Array
短 - > Int16Array
unsigned short - > Uint16Array
int - > Int32Array
unsigned int - > Uint32Array
float - > Float32Array
double - > Float64Array
MakeTypedArray
该函数有两种实现方式。两者都接受两个参数:指向任何上述数据类型的数组的指针,以及可选的大小参数。默认值为0,表示“直到底层数组的末尾”。返回的值是指向类型化数组实例的指针。

注意:返回的类型化数组引用与传递指针相同的内存,不进行任何复制以保证此操作的效率。修改内存时请小心,因为编译器可能会或可能不会理解类型化数组与指针的内存相同。此函数旨在以较低的开销将C ++数据传递给浏览器API。

隐式打字版本
template < typename P,typename T = typename TypedArrayForPointerType

:: type>
T MakeTypedArray(const P ptr,size_t size = 0)
此函数返回ptr指针底层内存的类型化数组。返回类型取决于模板助手ptr的映射,并遵循TypedArrayForPointerType模板助手的映射。

明确键入的版本
template < typename T>
T MakeTypedArray(const void ptr,size_t size = 0)
此函数返回ptr指针底层内存的类型化数组,返回类型必须由用户显式提供。任何指针类型都可以作为传递ptr,但如果底层内存不是基本数据类型的数组,则结果是未定义的行为。

MakeArrayBufferView
client :: ArrayBufferView MakeArrayBufferView(const void ptr,size_t size = 0)
返回ptr指针底层内存的无类型ArrayBufferView 。不执行数据复制,返回的对象与ptr指针的别名相同。关于有效的内存别名的安全注意事项MakeTypedArray也是有效的MakeArrayBufferView。

使用例子

static ArrayBuffer myJsSayHello (uint8 buffer) {

    Uint8Array * t = (Uint8Array *)cheerp::MakeArrayBufferView(buffer);
    auto array = cheerp::makeArrayRef(t);

    for( int i = 0 ; i < array->get_length(); i++ ) {
        array[i] = array[i] + 100 ;
        *(buffer+i) = array[i];
    }
    //{age:20, c:{age:21},hellow:"cheerp"}
    struct Data d ;
    d.age = 20;
    d.c   = {21};
    memcpy(d.hellow ,"cheerp", 7);
    myCppSayHello(d);///js调用wasm
    return cheerp::MakeArrayBufferView(array);

}

输入js把Uint8Array进来以后,经过我们的处理,如果返回的话,最好使用MakeArrayBufferView 把我们的智能指针包装成js的ArrayBuffer对象返回。

相关文章
|
11月前
|
存储 编译器
深入解析i++和++i的区别及性能影响
在我们编写代码时,经常需要对变量进行自增操作。这种情况下,我们通常会用到两种常见的操作符:i++和++i。最近在阅读博客时,我偶然看到了有关i++和++i性能的讨论。之前我一直在使用它们,但从未从性能的角度考虑过,这让我突然产生了兴趣。尽管它们看起来相似,但它们之间存在微妙而重要的区别。在本文中,我们将详细解释i++和++i之间的区别,以及它们对代码性能的影响。
336 1
深入解析i++和++i的区别及性能影响
|
12月前
|
C++
有趣的动态转换
有趣的动态转换
解决传入的请求具有过多的参数,该服务器支持最多 2100 个参数
解决传入的请求具有过多的参数,该服务器支持最多 2100 个参数
|
2月前
|
消息中间件 存储 Java
三类代码协同模式问题之压缩异常输出以提高性能和节省存储空间的问题如何解决
三类代码协同模式问题之压缩异常输出以提高性能和节省存储空间的问题如何解决
|
4月前
|
并行计算 索引 Python
讨论如何优化 DataFrame 操作,减少内存占用和提高执行速度
【5月更文挑战第19天】优化 DataFrame 操作涉及选择合适的数据类型、避免复制、使用向量化、高效迭代和设置索引。通过这些策略,如使用 `np.int8` 节省内存,直接修改列数据,利用 `itertuples`,设置分类数据类型,以及分块和并行计算,可以显著减少内存占用和提高执行速度,从而更好地处理大规模数据。实践中需结合具体情况综合运用,不断测试和优化。
152 2
|
4月前
|
编译器
LabVIEW使用数据引用减少内存
LabVIEW使用数据引用减少内存
45 2
|
监控 Cloud Native Java
字节码编程,Byte-buddy篇二《监控方法执行耗时动态获取出入参类型和值》
在前面的ASM、Javassist 章节中也有陆续实现过获取方法的出入参信息,但实现的方式还是偏向于字节码控制,尤其ASM,更是需要使用到字节码指令将入参信息压栈操作保存到局部变量用于输出,在这个过程中需要深入了解Java虚拟机规范,否则很不好完成这一项的开发。但!ASM也是性能最牛的。其他的字节码编程框架都是基于它所开发的。
682 0
字节码编程,Byte-buddy篇二《监控方法执行耗时动态获取出入参类型和值》
【C++之基于对象】计算3个长方柱的体积
【C++之基于对象】计算3个长方柱的体积
|
PyTorch 算法框架/工具
如何将网络参数初始化,或者如何将网络参数还原成原始参数状态
在以上代码中,_initialize_weights()方法用于对网络参数进行初始化。其中,init.ones_表示将权重初始化为1,init.zeros_表示将偏置初始化为0。 3. 如果想将网络参数恢复到初始状态,则可以重新调用_initialize_weights()方法
293 0
|
存储 程序员 C语言
如何进行C++动态转换
如何进行C++动态转换
如何进行C++动态转换