So sánh hiệu suất JavaScript đa luồng bản địa với WASM

Tác giả:Nhà phát minh định lượng, Ngày: 2023-02-23 17:35:24
Tags:Nhiều đường dây

Các nhà phát minh đã thử nghiệm định lượng từ tầng thấp của bản địa để JavaScript hỗ trợ nhiều chủ đề có ý nghĩa thực sự và thêm vào chức năng WASM, dưới đây là một bản demo để tải xuống và người quản lý mới nhất có thể thưởng thức trải nghiệm. Chức năng này là một chức năng Worker không phải JavaScript, có thể được sử dụng để giao tiếp giữa nhiều chuỗi hoặc giao tiếp với các chuỗi chính.

Bạn có thể tạo bài kiểm tra từ trang web này:https://wasdk.github.io/WasmFiddle/

Mã ngôn ngữ C được biên dịch thành wasm là:

int fib(int f) {
  if (f < 2) return f;
  return fib(f - 1) + fib(f - 2);
}

Sau khi biên dịch, tải xuống tệp wasm và chuyển đổi thành chuỗi hex bằng python

python -c "print('data:hex,'+bytes.hex(open('program.wasm','rb').read()))"

Bạn có thể thay đổi nội dung sau các biến trong mã

__Thread ((function, arguments...)

Tạo thread và trả về threadtid, chức năng của hàm chủ của thread được chấp nhận phải hoàn thành tất cả mã chức năng trong hàm, không hỗ trợ tham chiếu đến các chức năng đóng khác, có thể gọi tất cả các API nền tảng bên trong thread, nhưng không thể gọi các chức năng khác được người dùng tùy chỉnh

Một ví dụ đơn giản:

let tid = __Thread(function(x, y) {
    return x + y
}, 1, 2)
Log(__threadJoin(tid))

Ví dụ về các yêu cầu đa luồng:

function main() {
    let threads = [
        "https://www.baidu.com",
        "https://www.163.com"
    ].map(function(url) {
        return __Thread(function(url) {
            Log("GET", url)
            return HttpQuery(url)
        }, url)
    })
    threads.forEach(function(tid) {
        Log(__threadJoin(tid))
    })
}

Các biến lưu trữ cục bộ

Hỗ trợ thay đổi lưu trữ cục bộ cho các chuỗi, để dễ dàng chia sẻ dữ liệu mà không cần lưu trữ trên các chuỗi.__threadJoinChờ đợi để rút lui thành công hoặc__threadTerminateCó hiệu lực trong trường hợp chấm dứt

__threadGetData(tid, key)
__threadSetData(tid, key, value)

tid là 0 biểu thị cho chuỗi hiện tại, value không xác định biểu thị xóa key, hỗ trợ truy cập lẫn nhau giữa các chuỗi chia sẻ biến, giá trị phải là biến có thể sắp xếp

Truyền thông dây

__threadPostMessage(tid, msg) // 向指定线程发送消息, tid为0是向主线程即当前主函数发送, 在线程内部调用指向主线程回复消息, 该消息可以被EventLoop捕获
__threadPeekMessage(tid, timeout) // 从指定线程接收消息, 如果不指定timeout(毫秒)就一直等待, tid为0指等待主线程的消息

_threadJoin ((tid, timeout)

Đặt timeout (mm) để chỉ định thời gian chờ không thể chỉ định là chờ đến khi kết thúc, thành công trong việc trả về một cấu trúc có hàm trả về giá trị và thu hồi tài nguyên, cấu trúc như sau:

{
    id: tid, // 线程id
    elapsed: 1111, // 线程的运行时间(纳秒)
    terminated: false, // 线程是否被强制结束 
    ret: 123, // 线程函数的返回值
}

Nếu trễ trả về undefined

__threadTerminate ((tid))

Quyết định kết thúc thread và thu hồi tài nguyên (không thể sử dụng __threadJoin nữa khi chờ kết thúc)

Chú ý.

Chức năng __Thread không hỗ trợ tham chiếu các biến ngoài hàm (được thực hiện để chạy trong môi trường cô lập), tham chiếu các biến bên ngoài sẽ bị biên dịch thất bại


function main() {
    let cycle = 100
    let input = 30
    let threads = [
        __Thread(function(cycle, input) {
            function fib(f) {
                if (f < 2) return f
                return fib(f - 1) + fib(f - 2)
            }
            let ret = 0
            for (let i = 0; i < cycle; i++) {
                ret = fib(input);
                Log("javascript progress: ", i)
            }
            return 'javascript fib: ' + ret
        }, cycle, input),
        
        __Thread(function(cycle, input) {
            let data = 'data:hex,0061736d010000000186808080000160017f017f0382808080000100048480808000017000000583808080000100010681808080000007908080800002066d656d6f727902000366696200000aa480808000019e80808000000240200041024e0d0020000f0b2000417f6a10002000417e6a10006a0b'
            let m = wasm.parseModule(data)

            let instance = wasm.buildInstance(m, {
                stack_size: 65 * 1024 * 1024,
            })

            let ret = 0
            for (let i = 0; i < cycle; i++) {
                ret = instance.callFunction('fib', input)
                Log("wasm progress: ", i)
            }

            return 'wasm fib: ' + ret
        }, cycle, input)
    ]

    threads.forEach(function(tid) {
        let info = __threadJoin(tid)
        Log('#'+tid, info.ret, 'elapsed:', info.elapsed / 1e6, "#ff0000")
    })
}

Có liên quan

Thêm nữa

Dao xươngLời khuyên: lỗi ReferenceError: '__Thread' is not defined at main (FILE:5)

Nhà phát minh định lượngTăng cấp lên trình quản trị mới nhất