如果您定義THR,代碼將完成相同的作業,但只是在另一個執行緒中。我只測量了write通話時間。
用 運行代碼./some-file-name>/dev/null,這是我得到的結果,也就是累積的時鐘周期。
THR 沒有定義的
1 48930106
2 43946464
3 44669126
4 45918011
5 44108477
6 43608789
7 45104427
8 49676889
9 44682305
10 47516931
THR 定義
1 108347418
2 101670307
3 101726085
4 100531554
5 100137343
6 85837022
7 105556754
8 104681843
9 110303338
10 104666783
為什么write從另一個執行緒呼叫時會慢很多?
系統是Fedora Linux。
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
#include <fcntl.h>
#include <unistd.h>
#include <immintrin.h>
#ifdef __cplusplus
#include <atomic>
using namespace std;
#else
#include <stdatomic.h>
#endif
#define SIZE 0x100000
static unsigned long long rdtscp() {
unsigned _;
return __rdtscp(&_);
}
static char b[SIZE];
static atomic_ullong oc;
#ifdef THR
static sem_t s[2];
void *out(void *_) {
for (;;) {
sem_wait(s);
unsigned long long c = rdtscp();
write(1, b, SIZE);
oc = rdtscp() - c;
sem_post(s 1);
}
return _;
}
#endif
int main() {
memset(b, 'a', SIZE);
#ifdef THR
sem_init(s, false, 0);
sem_init(s 1, false, 0);
pthread_t t;
pthread_create(&t, NULL, out, NULL);
#endif
for (int i = 1;; i) {
#ifdef THR
sem_post(s);
sem_wait(s 1);
#else
unsigned long long c = rdtscp();
write(1, b, SIZE);
oc = rdtscp() - c;
#endif
const int d = 100000;
if (!(i % d)) {
unsigned long long _oc = atomic_exchange(&oc, 0);
fprintf(stderr, "Mllu\n", i / d, _oc);
}
}
}
不確定這是否可以,但我用 C 和 C 編譯代碼以添加 C 標記。如果這不合適,我會回滾。
uj5u.com熱心網友回復:
在一種情況下,要寫入的資料在內核的快取中很熱。沒有同步或調度開銷。
在另一種情況下,要寫入的資料在其他某個內核的快取中進行了修改。有同步和調度開銷。
當快取處于冷態、內核必須同步并且必須分派新任務而不是簡單地繼續現有任務時,處理資料需要更多時鐘周期也就不足為奇了。
一個常見的反模式是從一??個執行緒到另一個執行緒傳遞資料,而不是在單個執行緒中處理它直到完成。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/399889.html
上一篇:如何在kivy的執行緒上放置影片
下一篇:Java執行緒同步
