নেটিভ মাল্টি-থ্রেড জাভাস্ক্রিপ্ট এবং WASM এর পারফরম্যান্সের তুলনা

লেখক:উদ্ভাবক পরিমাণ, তারিখ: ২০২৩-০২-২৩ ১৭ঃ৩৫ঃ২৪
ট্যাগঃমাল্টি থ্রেড

উদ্ভাবকরা নেটিভ নিম্ন স্তর থেকে জাভাস্ক্রিপ্টকে সত্যিকারের অর্থপূর্ণ বহু-থ্রেড সমর্থন করার চেষ্টা করেছেন এবং WASM বৈশিষ্ট্যটি যুক্ত করেছেন। নীচে একটি ডেমো রয়েছে যা সর্বশেষতম হোস্টগুলি ডাউনলোড করতে পারে এটি একটি অ-জাভাস্ক্রিপ্ট ওয়ার্কার বৈশিষ্ট্য যা একাধিক থ্রেডের মধ্যে একে অপরের সাথে বা মূল থ্রেডের সাথে যোগাযোগ করতে ব্যবহার করা যেতে পারে।

C ভাষার ট্রান্সফারওয়াসম এই ওয়েবসাইট থেকে টেস্ট তৈরি করতে পারেঃhttps://wasdk.github.io/WasmFiddle/

C ভাষার কোড যা wasm নামে কম্পাইল করা হয়েছে তা হলঃ

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

সংকলন এবং ডাউনলোডের পরে wasm ফাইলটি পাইথনে হেক্স স্ট্রিংতে রূপান্তরিত হয়

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

পরিবর্তিত কোডের ভেরিয়েবলের পিছনে থাকা বিষয়বস্তু

__থ্রেড ((ফাংশন, যুক্তি...)

একটি থ্রেড তৈরি করুন এবং থ্রেডটিড ফিরিয়ে আনুন, গ্রহণযোগ্য থ্রেডের মূল ফাংশনের ফাংশনগুলিকে থ্রেড ফাংশনের মধ্যে সমস্ত ফাংশন কোড সম্পন্ন করতে হবে, অন্যান্য বন্ধ ফাংশনের রেফারেন্স সমর্থন করে না, থ্রেডের মধ্যে সমস্ত প্ল্যাটফর্মের এপিআই কল করা যায়, তবে ব্যবহারকারীর কাস্টমাইজড অন্যান্য ফাংশনগুলি কল করা যায় না

একটি সহজ উদাহরণঃ

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

মাল্টি-থ্রেড অনুরোধের উদাহরণঃ

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))
    })
}

থ্রেডের স্থানীয় স্টোরেজ ভেরিয়েবল

থ্রেডের স্থানীয় স্টোরেজ ভেরিয়েবল সমর্থন করে, যাতে ডাটা শেয়ার করা সহজ হয়।__threadJoinসফলভাবে প্রত্যাহারের জন্য অপেক্ষা করুন অথবা__threadTerminateসমাপ্তির ক্ষেত্রে কার্যকর

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

tid হল 0 যা বর্তমান থ্রেডকে নির্দেশ করে, value unspecified যা মুছে ফেলা keyকে নির্দেশ করে, যা থ্রেডগুলির মধ্যে পারস্পরিক অ্যাক্সেসযোগ্য শেয়ারিং ভেরিয়েবলকে সমর্থন করে, যার মানগুলি অবশ্যই সেরিয়েবল ভেরিয়েবল হতে হবে

থ্রেড যোগাযোগ

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

__threadJoin ((টাইড, টাইমআউট)

থ্রেডের শেষের জন্য অপেক্ষা করুন টাইমআউট (মিলিসেকেন্ড) নির্দিষ্ট করুন টাইমআউট নির্দিষ্ট করার জন্য অপেক্ষা করুন থ্রেডের শেষ না হওয়া পর্যন্ত অপেক্ষা করুন, সফলভাবে একটি ফাংশন রিটার্ন মান সহ একটি কাঠামো ফিরে আসে এবং রিসোর্সগুলি পুনরুদ্ধার করে, কাঠামোটি নিম্নরূপঃ

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

যদি ওভারটাইম রিটার্ন undefined হয়

__threadTerminate(tid)

বাধ্যতামূলকভাবে থ্রেড বন্ধ করুন এবং সম্পদ পুনরুদ্ধার করুন ((_threadJoin শেষ হওয়ার অপেক্ষা করতে আর ব্যবহার করা যাবে না))

সাবধান!

__Thread এর ফাংশনটি ফাংশনের বাইরের ভেরিয়েবলগুলিকে রেফারেন্স করে না (এটি একটি বিচ্ছিন্ন পরিবেশের জন্য কাজ করে) এবং বাইরের ভেরিয়েবলগুলিকে রেফারেন্স করলে কম্পাইল ব্যর্থ হবে


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")
    })
}

সম্পর্কিত

আরো

হাড়ের ছুরিরান টিপঃ ত্রুটি ReferenceError: '__Thread' is not defined at main (FILE:5)

উদ্ভাবক পরিমাণসর্বশেষ হোস্ট আপগ্রেড করুন