你能想到为什么原子操作看起来比信号量慢,即使指令减少了吗?
示例代码:
void increment(){
if (strcmp(type, "ATOMIC") == 0) {
for (int i = 0; i < RUN_TIME; ++i) {
atomic_fetch_add_explicit(&count, 1, memory_order_relaxed);
}
}
if (strcmp(type, "SEMAPHORE") == 0){
for (int i = 0; i < RUN_TIME; ++i) {
sem_wait(sem);
count++;
sem_post(sem);
}
}
}
输出:
time ./CMAIN "SEMAPHORE";time ./CMAIN "ATOMIC";
[C] SEMAPHORE, count 4000000
real 0m0.039s
user 0m0.029s
sys 0m0.002s
[C] ATOMIC, count 4000000
real 0m0.092s
user 0m0.236s
sys 0m0.003s
无法复制。对于 10^9 次迭代,我得到(来自 bash、i5、x86_64、Linux(:
$ TIMEFORMAT="%RR %UU %SS"
$ gcc atomic.c -Os -lpthread && ( time ./a.out ATOMIC ; time ./a.out SEMAPHORE )
1.572R 1.568U 0.000S #ATOMIC
5.542R 5.536U 0.000S #SEMAPHORE
(4000000 次迭代的比率大致相同。
我的atomic.c(填写空白的示例(:
#include <stdio.h>
#include <string.h>
#include <stdatomic.h>
#include <semaphore.h>
#define RUN_TIME 100000000
char * type;
sem_t *sem;
_Atomic int count = ATOMIC_VAR_INIT(0);
void increment(){
if (strcmp(type, "ATOMIC") == 0) {
for (int i = 0; i < RUN_TIME; ++i) {
atomic_fetch_add_explicit(&count, 1, memory_order_relaxed);
}
}
if (strcmp(type, "SEMAPHORE") == 0){
for (int i = 0; i < RUN_TIME; ++i) {
sem_wait(sem);
count++;
sem_post(sem);
}
}
}
int main(int C, char**V)
{
sem_t s;
sem_init(&s, 0, 1);
sem = &s;
type = V[1];
increment();
}
请发布 mcve 以及您的平台规格。
它不应该,因为我读到的是"在信号量中 当某些进程尝试访问不可用的信号量时,信号量将进程置于等待队列 (FIFO( 并将任务置于睡眠状态,CPU 而不是原子操作更耗时或开销更多。
通常原子操作会执行得更快,因为它会一起加载、更新和修改指令。但是原子操作是特定于CPU的,即n++将在单个指令(INC(中执行或不执行,总是无法保证。所以由CPU决定,可能是因为这个原因,你得到这样的输出。
我理解我写的,建议将不胜感激。