WebAssembly多线程demo

WebAssembly多线程demo

一、准备工作

WebAssembly第一个demo
chrome://flags WebAssembly threads support 选项要打开 enable

二、好了,开始写demo

功能:js传递给c 一个计算次数,一个启动的线程数, 打印相同计算次数下,单线程和多线程的计算时间

1、新建一个目录,创建两个文件index.html和main.cpp

2、main.cpp内容

#include <iostream>
#include <future>
#include <math.h>
#include <vector>
#include <chrono>
#include <sstream>
#include <emscripten.h>
#include <unistd.h>

using namespace std;
using namespace chrono;


//相加
int add(int start,int end){
int result = 0;
for(int i = start;i<end;i++){
result += i;
usleep (1000);
}
return result;
}

//线程
int openThreadAndAdd(int size,int threadNum){

//创建线程结果存放数组
vector<future<int>> futures;
futures.reserve(threadNum);

//每个线程计算多少个<相加>
double step = ((double)size / (double)threadNum);
step = ceil(step);
long startIndex = 0;
long endIndex = step;


for(long i=0;i < threadNum; i++){

//启动线程
auto future = async(launch::async,add,startIndex,endIndex);

//把线程结果存在数组里
futures.push_back(move(future));

//步进
startIndex += step;
endIndex += step;

//判断是否结束
if(endIndex > size ){
endIndex = size;
}
}

//把多线程的计算结果<相加>
int total = 0;
for(auto& future : futures){
total = add(total,future.get());
}

//回收数组
futures.clear();

return total;
}

//获取当前时间
system_clock::time_point getTime(){
return system_clock::now();
}

//获取时间差
double cost(system_clock::time_point start){
system_clock::time_point end = getTime();
auto duration = duration_cast<microseconds>(end - start);
double cost = double(duration.count()) * microseconds::period::num / microseconds::period::den;
return cost;
}

//计算单线程和多线程,并打印结果
const char* computer(int size,int threadNum){
//多线程
auto start1 = getTime();
int total_thread = openThreadAndAdd(size,threadNum);
double costTime1 = cost(start1);

//单线程
auto start2 = getTime();
int total = add(0,size);
double costTime2 = cost(start2);

//生成结果字符串
string str = "thread:" + to_string(total_thread) + " cost:" + to_string(costTime1) + "\n";
str = str + "normal:" + to_string(total) + " cost:" +to_string(costTime2);
const char* result = str.c_str();

return result;
}

extern "C" {
EMSCRIPTEN_KEEPALIVE
const char* jsCallC(int size,int threadNum) {
cout << "jsCallC" << endl;
const char* result = computer(size + 1,threadNum);
return result;
}
}
  • 给js调用的方法必须标注EMSCRIPTEN_KEEPALIVE

3、index.html内容

<!DOCTYPE html>
<html>
<head>
<script src="./webassembly.js"></script>
</html>
<script type="text/javascript">

function fun(){

var size = 1000
var threadNum = 4;
var outputPtr = Module._jsCallC(size,threadNum)
var outputStr = Module.UTF8ToString(outputPtr) //排序结果指针转字符串

console.log(outputStr);

Module._free(outputPtr);
}

初始化webasembly
Module.onRuntimeInitialized = function() {
console.log("ModuleWASM_INSTANCE init finish")
fun()
}

</script>

4、编译

emsdkDir='emsdk的路径'
emsdk activate latest
source ${emsdkDir}/emsdk_env.sh

emcc main.cpp \
-std=c++11 \
-s WASM=1 \
-s EXTRA_EXPORTED_RUNTIME_METHODS=["UTF8ToString"] \
-s EXPORTED_FUNCTIONS=["_jsCallC"] \
-pthread \
-s PROXY_TO_PTHREAD=1 \
-s USE_PTHREADS=1 -s PTHREAD_POOL_SIZE=7 \
-s TOTAL_MEMORY=512MB --memory-init-file 1 \
-O1 -o webassembly.js
  • -pthread -s USE_PTHREADS=1 -s PROXY_TO_PTHREAD=1 开启多线程
  • -s PTHREAD_POOL_SIZE=7 开启7个线程
  • -s TOTAL_MEMORY=512MB 多线程需要制定内存容量
  • –memory-init-file 1 指定开辟单独的内存,和上面一个参数同时使用
  • 注意:开启多线程时,开启-s MODULARIZE=1会有问题

启动服务在控制台看看效果:

  • python2:python -m SimpleHTTPServer 8080
  • python3:python -m http.server 8080

  • 浏览器打开http://localhost:8080/

三、编译参数说明

*https://github.com/emscripten-core/emscripten/blob/master/src/settings.js

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值