ハードウェアサポートによる重要な問題の解決

10821 ワード

ハードウェアベースのソリューション


ソフトウェアベースの問題解決策


petersonソリューションのようなソフトウェアベースのソリューションは、最新のコンピュータアーキテクチャでコマンド順序の再ソートの問題が発生する可能性があります.したがって、ハードウェアは、特別な命令によってソリューションをサポートします.

メモリ障害(Memory Barriers)


コンピュータアーキテクチャがアプリケーションにメモリアクセスを提供する際に保証される事項を決定する方法をメモリモデルと呼ぶ.

強み


1つのプロセッサのメモリの変更は、他のすべてのプロセッサに直ちに表示されます.

弱序


1つのプロセッサのメモリの変更は、他のすべてのプロセッサにすぐに表示されません.

メモリモデルの問題点


メモリモデルに基づいて、メモリ変更の結果を特定できません.これらの問題を解決するには、メモリバーまたはメモリバーを使用します.


次の例では、flag値がx値より先にロードされていることを確認します.
while(!flag)
	memory_barrier();    
print x;
次の例では、x値がflag値より先にロードされていることを確認します.
x=100;
memory_barrier();
flag=true;

ハードウェア命令(Hardware Instruction)


以下で説明する2つのハードウェアコマンドは、原子的に実行されます.命令が原子的に実行されるということは,2つの命令が同時に実行されてもスケジューリングが中断されず,常に順番に実行されることを意味する.コマンドが実行されたら、コマンドが終了する前に現在のコマンドのみが実行されていることを確認します.

test and set()の定義

boolean test_and_set(boolean *target){
	boolean rv = *target;
    *target = true;
    
    return rv;
}

test and set()を使用して反発(反発)を実現

do{
	while(test_and_set(&lock));
    
	/* critical section */
    
	lock = false;
    
	/* remainder section */
    
}while(true);

compare and swap()の定義

int compare_and_swap(int *value, int expected, int new_value){
	int temp = *value;
    
	if (*value == expected)
		*vaule = new_value;

	return temp;
}

compare and swap()を使用して反発(反発)を実現

while(true){
	while(compare_and_swap(&lock, 0, 1) != 0);
    
	/* critical seciton */
    
	lock = 0;
    
	/* remainder section */
}

反発はcompare and swap()を用いて限られた待機条件を満たす

while (true) {
        waiting[i] = true;
        key = 1;
        
        while (waiting[i] && key == 1)
            key = compare_and_swap(&lock, 0, 1);

        waiting[i] = false;

        /* critical section */

        j = (i + 1) % n;
        while ((j != i) && !waiting[j])
            j = (j + 1) % n;

        if (j == i)
            lock = 0;
        else
            waiting[j] = false;
        
        /* remainder section */
    }

げんしへんすう


上記の比較and swap()は、反発を提供するために直接使用されない.逆に、重要な部分の問題を解決する他のツールを構築するための基本的なコンポーネントとして使用されます.このように実現されるツールは、対応するデータ型の原子演算を提供する原子変数(原子変数)である.

Yes-原子の整数を増やす関数()

void increment(atomic_int *v){
	int temp;
    
	do{
	    temp = *v;
	}while(temp != compare_and_swap(v, temp, temp+1));
}

に質問


原子演算をサポートするため,反発は保証できる.しかし、すべての場合、race conditionは解決できません.
例えば、この文章に記載された生産者消費者モードのコードを参照する.
count変数を原子整数として定義できます.しかし、消費者が複数のプロセスである場合、消費者においてcount値が変更されるとcount != 0になり、whileゲートから脱出してデータを消費する.私たちは1つの消費者が1つのデータを消費すると考えていますが、実際には1つのデータが2つの消費者に消費される問題が発生します.