[Обновление:] Теперь я создаю несколько процессов, и это работает довольно хорошо, хотя основная проблема с потоками все еще существует. [/]
Я пытаюсь запустить программу на С++ (g++ 4.6.1), которая компилирует кучу ядер opencl. Большая часть времени проводится внутри clBuildProgram. (Это генетическое программирование, и на самом деле запуск кода и оценка пригодности выполняются намного быстрее.) Я пытаюсь выполнить компиляцию этих ядер и пока безуспешно. На данный момент нет общих данных между потоками (кроме одинаковой платформы и ссылки на устройство), но он будет запускать только один поток за раз. Я могу запустить этот код как несколько процессов (просто запуская их в разных окнах терминала в Linux), и тогда он будет использовать несколько ядер, но не в рамках одного процесса. Я могу использовать несколько ядер с одним и тем же базовым кодом многопоточности (std::thread) только с базовой математикой, поэтому я думаю, что это как-то связано либо с компиляцией opencl, либо с некоторыми статическими данными, о которых я забыл. :) Любые идеи? Я сделал все возможное, чтобы сделать это потокобезопасным, поэтому я в тупике.
Я использую AMD SDK (opencl 1.1, около 13.06.2010) и 5830 или 5850 для его запуска. SDK и g++ не так актуальны, как могли бы быть. В последний раз, когда я устанавливал более новый дистрибутив Linux, чтобы получить более новый g++, мой код работал на половинной скорости (по крайней мере, компиляции opencl), поэтому я вернулся. (Только что проверил код этой установки, и он работает на половинной скорости, по-прежнему без различий в многопоточности.) Кроме того, когда я сказал, что он запускает только один поток за раз, он запускает их все, а затем чередует два, пока они не закончатся, затем выполните следующие два и т. д. И похоже, что все потоки выполняются до тех пор, пока код не перейдет к сборке программы. Я не использую функцию обратного вызова в clBuildProgram. Я понимаю, что здесь многое может пойти не так, и трудно сказать без кода. :)
Я почти уверен, что эта проблема возникает внутри или при вызове clBuildProgram. Я печатаю время, затраченное здесь, и потоки, которые были отложены, вернутся с большим временем компиляции для своей первой компиляции. Единственными общими данными между этими вызовами clBuildProgram является идентификатор устройства, поскольку cl_device_id каждого потока имеет одинаковое значение.
Вот как я запускаю потоки:
for (a = 0; a < num_threads; a++) {
threads[a] = std::thread(std::ref(programs[a]));
threads[a].detach();
sleep(1); // giving the opencl init f()s time to complete
}
Вот где он увяз (и это все передаваемые локальные переменные, хотя идентификатор устройства будет таким же):
clBuildProgram(program, 1, & device, options, NULL, NULL);
Кажется, не имеет значения, имеет ли каждый поток уникальный контекст или command_queue. Я действительно подозревал, что это была проблема, поэтому я упоминаю об этом. :)
Обновление: для этого будет работать создание дочерних процессов с помощью fork().