在多线程共享进程中,原子操作似乎比Semaphore操作慢

时间:2017-11-10 14:54:45

标签: c multithreading semaphore atomic operations

你能否考虑为什么原子操作看起来比信号量慢,尽管指令有所减少?

示例代码:

 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

2 个答案:

答案 0 :(得分:0)

它不应该因为我读到的是“在信号量中当某个进程试图访问不可用的信号量时,信号量将进程置于等待队列(FIFO)并将任务置于睡眠状态 ,它比CPU更耗时或更多开销,而不是原子操作。

通常原子操作会执行得更快,因为它会加载,更新和放大一起修改指令。但原子操作是CPU特定的,即n ++将在单指令(INC)中执行或不执行,始终无法保证。所以由CPU决定,可能是因为这个原因你得到这样的输出。

我理解的是我写的,建议将不胜感激。

答案 1 :(得分:0)

无法复制。对于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以及您的平台规范。