当前位置: 首页 > 工具软件 > Cheerp > 使用案例 >

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

殳自怡
2023-12-01

这个文章主要描述在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对象返回。

 类似资料: