모든 스레드가 자유롭게 실행되는 작업을 게시 할 수있는 일반 작업 시스템을 구축하려고합니다. 이전 시도에서 나는 어느 시점에 차단할 것이기 때문에 스레드가 부족한 경우가 많았습니다. 그래서 섬유를 강화하려고합니다. 하나의 섬유 블록이 스레드가 다른 섬유에서 자유롭게 작동 할 때, 완벽하게 들립니다.boost.fibers에서 work_stealing 스케줄러를 사용하는 방법
작업 도용 알고리즘은 제 목적에 이상적인 것 같지만 사용하기가 어렵습니다. 예제 코드에서 파이버가 생성되고 스레드와 스케줄러 만 생성되므로 모든 파이버가 실제로 모든 스레드에서 실행됩니다. 하지만 나중에 파이버를 시작하려고합니다. 그러면 다른 모든 스레드는 아무런 작업도하지 않아 무기한으로 일시 중단됩니다. 나는 그들을 다시 깨울 어떤 방법도 찾지 못했고, 모든 섬유는 주 스레드에서만 수행됩니다. "notify"는 호출하는 메소드 인 것 같지만 실제로 알고리즘의 인스턴스에 도달하는 방법은 없습니다.
나는 notify()를 호출 할 수 있도록 알고리즘의 모든 인스턴스에 대한 포인터를 유지하려고 시도했지만 실제로 도움이되지 않는다. 대부분의 경우 작업자 스레드의 알고리즘은 다음 스레드가 dispatcher_context이기 때문에 주 스레드의 알고리즘을 훔칠 수 없습니다.
"일시 중단"을 비활성화 할 수는 있지만 스레드는 옵션이 아닌 대기 중입니다.
나는 또한 shared_work 알고리즘을 시도했다. 동일한 문제는 스레드가 광섬유를 찾지 못하면 다시는 깨어나지 않을 것입니다. 나는 notify(), 같은 결과를 수동으로 호출하는 것과 같은 해킹을 시도했지만 매우 신뢰할 수 없었다.
채널을 사용해 보았지만 AFAICT가 광섬유를 기다리는 중이면 현재 컨텍스트가 "홉 (hoop)"되고 대기중인 광섬유가 실행되어 현재 광섬유가 일시 중단됩니다.
간단히 말해서 나는 다른 스레드에서 광섬유를 안정적으로 작동시키는 것이 매우 어렵다는 것을 알게되었습니다. 대부분의 스레드를 프로파일 링 할 때 condition_variable을 기다리고 있습니다. 비록 내가 많은 수의 섬유를 만들었지 만. 내가 의도적으로 바쁜 CPU를 시뮬레이션 할 수 this_thread :: sleep_for 사용하고
std::vector<boost::fibers::future<int>> v;
for (auto i = 0; i < 16; ++i)
v.emplace_back(boost::fibers::async([i] {
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
return i;
}));
int s = 0;
for (auto &f : v)
s += f.get();
: 작은 테스트 케이스 내가 노력하고 있습니다로
.
이 코드가 1에서 실행될 것으로 예상되지만, 대부분 16s가됩니다. 이 예제를 실제로 해킹 할 수있는 1 초 만에 실행할 수있었습니다. 그러나 "옳은"느낌이 전혀 들지 않으며 다른 시나리오에서는 효과가 없었습니다. 특정 시나리오에서는 항상 손수 제작해야했습니다.
이 예제는 work_stealing 알고리즘으로 예상대로 작동해야한다고 생각합니다. 나는 무엇을 놓치고 있습니까? 섬유의 오용인가요? 어떻게 이것을 신뢰할 수있게 구현할 수 있습니까?
덕분 딕스
나는'boost :: fibers'를 한번도 사용하지 않았습니다. 그러나,'std :: async'와'std :: future'와 같은 것이면,'get'이 호출 될 때 당신은 섬유를 시작하는 것만 같습니다. 'get '이 블로킹하기 때문에'for' 루프를 통한 첫 번째 반복은 1 초가 걸릴 것입니다. 그런 다음'get'가 다음 요소에서 호출되어 1 초가 걸립니다.'v'의 각 요소에 대해'f.wait_for (std :: chrono :: second (0))'를 먼저하면 어떨까요? – Darhuuk
std :: future가 다른 스레드에서 즉시 시작되거나 get()이 호출 될 때 기술적으로 런타임에 달려 있다고 생각합니다. 나는 wait_for가 미래를위한 문제를 해결할 수 있는지 시험해 볼 것이다. 그러나 미래는 여기에 나와있을 수있는 가장 짧은 예일뿐입니다. 대부분의 경우 나는 그들과 일하지 않습니다. – Dix