Lors du développement de stratégies sur FMZ en utilisant le langage JavaScript, puisque l'architecture de stratégie est interrogée.exchange.Go
Cette fonction est utilisée pour faire des appels simultanés à certaines interfaces, afin de répondre aux exigences de certains scénarios simultanés. Mais si vous voulez créer un seul thread pour effectuer une série d'opérations, c'est impossible.threading
bibliothèque pour faire une conception simultanée.
En fonction de cette exigence, la plateforme FMZ a mis à niveau la couche inférieure du système.
Ensuite, je vais vous aider à comprendre chaque fonction une par une.
Le__Thread
fonction peut créer un thread et exécuter une fonction simultanément.func1
Qu'est-ce que lefunc1
Pour voir le processus d'accumulation progressive, nous utilisons la boucle for dans la fonction func1 pour faire une pause à chaque fois (la fonction Sleep est utilisée pour dormir pendant un certain nombre de millisecondes) pendant une certaine période de temps.
function func1(sleepMilliseconds) {
var sum = 0
for (var i = 0 ; i < 10 ; i++) {
sum += i
Sleep(sleepMilliseconds)
Log("sum:", sum)
}
return sum
}
function main() {
// Use the __Thread function to create a thread concurrently, and the parameter 200 is the parameter of the func1 function,
// If the func1 function has multiple parameters, here we pass the corresponding parameters.
var thread1Id = __Thread(func1, 200)
// Here we need to wait for the execution result of the thread whose thread Id is thread1Id, otherwise all threads will be released directly after the main function is executed.
var ret = __threadJoin(thread1Id)
Log("ret:", ret)
}
Dans les applications pratiques, nous pouvons faire des requêtes http simultanément comme ceci:
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))
})
}
Dans l'exemple ci-dessus, nous avons utilisé le__threadJoin
fonction dans la fonction principale enfin d'attendre que les threads concurrents pour terminer l'exécution.ret
reçoit la valeur de retour de la__threadJoin
fonction, et nous imprimons la valeur de retour, nous pouvons observer les résultats spécifiques de l'exécution simultanée du thread.
// id: thread ID, terminated: whether it was forced to stop, elapsed: time-consuming (nanoseconds), ret: the return value of the thread execution function
ret: {"id":1,"terminated":false,"elapsed":2004884301,"ret":45}
function func1(sleepMilliseconds) {
var sum = 0
for (var i = 0 ; i < 10 ; i++) {
sum += i
Sleep(sleepMilliseconds)
Log("sum:", sum)
}
return sum
}
function main() {
var thread1Id = __Thread(func1, 200)
Sleep(1000)
retThreadTerminate = __threadTerminate(thread1Id)
Log(retThreadTerminate) // true
}
Nous utilisons toujours l'exemple juste maintenant, après avoir créé un thread, vous pouvez mettre fin de force à l'exécution du thread après avoir attendu 1 seconde.
La communication inter-thread utilise principalement le__threadPostMessage
fonction et le__threadPeekMessage
Nous allons examiner l'exemple simple suivant:
function func1() {
var id = __threadId()
while (true) {
var postMsg = "Message from thread function func1" with "from id:" + id +
__threadPostMessage(0, postMsg) // Send a message to the main thread
var peekMsg = __threadPeekMessage(0) // Receive messages from the main thread
Log(peekMsg)
Sleep(5000)
}
}
function main() {
var threadId = __Thread(func1)
while (true) {
var postMsg = "Messages from the main function of the main thread"
__threadPostMessage(threadId, postMsg)
var peekMsg = __threadPeekMessage(threadId)
Log(peekMsg, "#FF0000") // #FF0000 , Set the log to red for distinction
Sleep(5000)
}
}
Le__threadPostMessage
Le premier paramètre est l'ID du fil spécifique à envoyer, et le deuxième paramètre est le message à envoyer, qui peut être une chaîne, une valeur, un tableau ou un objet JSON, etc. Les messages peuvent être envoyés au fil principal dans des fonctions de fil concurrentes, et l'ID du fil principal est défini comme 0.
Le__threadPeekMessage
le premier paramètre est de surveiller l'ID spécifique du thread. Le deuxième paramètre peut définir le temps d'arrêt (en millisecondes), ou il peut être défini sur -1, ce qui signifie le blocage, et il ne reviendra pas jusqu'à ce qu'il y ait un message. Nous pouvons écouter le message envoyé par le thread principal au thread actuel dans la fonction de thread concurrent, et l'ID du thread principal est défini comme 0.
Bien sûr, à l'exception des threads concurrents qui communiquent avec le thread principal.
Dans l'exemple précédent,var id = __threadId()
est utilisé, et le__threadId()
fonction peut obtenir l'ID du fil actuel.
En plus de la communication entre les threads, les variables partagées peuvent également être utilisées pour l'interaction.
function testFunc() {
__threadSetData(0, "testFunc", 100) // Stored in the current thread environment, key-value pair testFunc : 100
Log("testFunc execution completed")
}
function main() {
// threadId is 1, the created thread with threadId 1 will be executed first, as long as the thread resources are not reclaimed, the variables stored locally in the thread will be valid
var testThread = __Thread(testFunc)
Sleep(1000)
// export in main, get testFunc: 100
Log("in main, get testFunc:", __threadGetData(testThread, "testFunc")) // Take out the value whose key name is testFunc
}
Ce qui précède est une démonstration simple de toutes les fonctions.
Cette stratégie de test s'adresse à:https://www.fmz.com/strategy/401463
Au premier coup d'œil, vous ne savez peutêtre pas ce que cette stratégie de test fait.
Then the test strategy is to compare the execution efficiency of wasm and javascript, but when comparing, the two execution methods can be executed successively, and the time-consuming of each is counted. It is also possible to allow the two execution methods to execute concurrently, and the statistics are time-consuming. Now that the underlying concurrency implementation of the JavaScript language strategy has been supported, the test strategy uses a concurrent method to compare naturally and compare the execution speed of the same algorithm.
- Algorithm of C language version, fib function
// Algoritme récursif des nombres de Fibonacci en langage C Int fib ((int f) { si (f < 2) renvoie f; Retour fib ((f - 1) + fib ((f - 2); Je ne sais pas.
- JavaScript language version of the algorithm, fib function
// Un algorithme récursif pour les mêmes nombres de Fibonacci, écrit en JavaScript fonction fib ((f) { si (f < 2) renvoie f Retour fib ((f - 1) + fib ((f - 2) Je ne sais pas.
It can be seen that the logic of the two fib function algorithms is exactly the same. The following is the source code of the test strategy:
fonction principale
// Afin de rendre plus facile de voir le code, j'écris le commentaire sur le code suivant directement:
laissez cycle = 100 // Le test exécute la boucle 100 fois
laisser l'entrée = 30 // Les paramètres qui seront transmis à la fonction fib algorithme
laissez les fils = [
__Thread(function(cycle, input) { // Un thread est créé simultanément pour effectuer des calculs en utilisant la version JavaScript de la fonction fib
fonction fib ((f) { // L'algorithme spécifique utilisé pour les tests, la fonction fib
si (f < 2) renvoie f
Retour fib ((f - 1) + fib ((f - 2)
Je ne sais pas.
laissez ret = 0
pour (I = 0; i < cycle; i++) { // boucle pendant 100 fois
ret = fib(input); // Appeler la fonction fib du langage JavaScript
Log ((
__Thread(function(cycle, input) { // Run a thread concurrently to perform calculations using the wasm version of the fib function
let data = 'data:hex,0061736d010000000186808080000160017f017f0382808080000100048480808000017000000583808080000100010681808080000007908080800002066d656d6f727902000366696200000aa480808000019e80808000000240200041024e0d0020000f0b2000417f6a10002000417e6a10006a0b'
let m = wasm.parseModule(data) // The data variable is the hex string of the wasm-encoded C language fib function, and the wasm model m is created using wasm.parseModule
let instance = wasm.buildInstance(m, { // Model instantiation, allocate a certain stack space
stack_size: 65 * 1024 * 1024,
})
let ret = 0
for (let i = 0; i < cycle; i++) { // loop for 100 times
ret = instance.callFunction('fib', input) // Calling the fib function code in the wasm instance is equivalent to calling the int fib(int f) function
Log("wasm progress: ", i)
}
return 'wasm fib: ' + ret
}, cycle, input)
]
// The elements in the threads array are the IDs returned by the __Thread function
threads.forEach(function(tid) {
let info = __threadJoin(tid) // Use the __threadJoin function to wait for two concurrent threads to execute and get the execution result
Log('#'+tid, info.ret, 'elapsed:', info.elapsed / 1e6, "#ff0000") // output execution result
})
}
Simply put, WASM is a program code with higher execution efficiency. In the example, we convert the c language code of "Fibonacci number recursive algorithm" into WASM. The process is like this:
1. Compile a piece of C language function code into wasm code.
We can use the website to convert: https://wasdk.github.io/WasmFiddle/
// Algoritme récursif des nombres de Fibonacci en langage C Int fib ((int f) { si (f < 2) renvoie f; Retour fib ((f - 1) + fib ((f - 2); Je ne sais pas.
2. Further encode the wasm code into a hex string.
The following commands can be used:
python -c
The encoded hex string is ```let data = 'data:hex,0061736d0100000001868...``` in the code.
3. Then parse it into a wasm model through the function ```wasm.parseModule()``` integrated by FMZ.
4. Create a wasm model instance through the function ```wasm.buildInstance()``` integrated by FMZ.
5. Then call the ```fib``` function in this wasm model instance, namely: ```ret = instance.callFunction('fib', input)```.
## Create a real bot to run the test
This test strategy can only be used for real bot testing. JavaScript multi-threading functions do not support backtesting so far.
```wasm``` and ```JavaScript``` execution comparison, the final execution results:
L'information n°2 a été diffusée à l'adresse:
Il n'y a pas d'autre moyen de le faire.
It seems that
Le wasm