CUDA 强制 OpenMP 以单线程模式运行

问题描述 投票:0回答:1

我编写了一个CUDA SGEMM程序,当我想用多线程CPU实现来测试速度时,它无法以多线程方式运行。我将 CPU 实现隔离在一个单独的

.cc
文件中,构建并运行它,没有任何问题。
.cu
和孤立的
.cc
中的代码(相同):

void sgemm_cpu_multi_threading(
    float* A, float* B, float* C, 
    float alpha, float beta, const int M, const int N, const int K
) {
    #pragma omp parallel for num_threads(8)
    for (int m = 0; m < M; m++) {
        printf("%d thread(s) can be used\n", omp_get_num_threads());
        for (int n = 0; n < N; n++) {
            float psum = 0.0;
            for (int k = 0; k < K; k++) {
                psum += A[m * K + k] * B[k * N + n];
            }
            C[m * N + n] = C[m * N + n] * beta + psum * alpha;
        }
    }
}

int main() {
    omp_set_num_threads(OMP_THREADS);   // OMP_THREADS=8
    // ... 
    sgemm_cpu_multi_threading(A, B, C, alpha, beta, M, N, K);
    // ...
}

在CUDA程序中,printf总是输出“1 thread(s) can be use”并且执行确实是序列化的。虽然隔离的纯 cxx 可执行文件告诉我“可以使用8个线程”。 我的 CMakeLists.txt (CUDA)。对于孤立的cxx项目,我只删除与CUDA相关的行。

cmake_minimum_required(VERSION 3.10)

project(SGEMM CUDA CXX)

if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE "Release")
endif()

SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall -fopenmp")
SET(COMPILE_CUDA True)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CUDA_ARCHITECTURES 75)

find_package(OpenMP REQUIRED)
if (OPENMP_FOUND)
  set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
  set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif()

include_directories(
    ${CMAKE_SOURCE_DIR}/../
)

add_executable(matmul ./matmul.cu)

target_link_libraries(matmul pthread OpenMP::OpenMP_CXX)

有人可以告诉我这是怎么回事吗?为什么我无法在 CUDA 程序中正确使用 OpenMP 多线程?顺便说一句,如果你想知道,A、B、C 可以使用

new
cudaMallocHost
进行分配,这不会影响我不能用多个线程运行程序的事实,即使CPU 功能需要通过 nvcc 分离并在 CPU 上编译和运行。

c++ multithreading cmake cuda openmp
1个回答
0
投票

正如@RobertCrovella 所提到的,我的代码未正确编译,

CMAKE_CUDA_FLAGS
未正确设置。解决方案非常简单,使用:

find_package(OpenMP REQUIRED)
if (OPENMP_FOUND)
  set (CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} ${OpenMP_CXX_FLAGS}")
endif()

而不是在 CMake 中设置 c 和 cxx 标志。我通过

${OpenMP_CXX_FLAGS}
检查了
message
的内容,它写了
-fopenmp
(没有别的),所以不需要再写
-fopenmp
。另外,我可以在没有
-Xcompiler
的情况下编译代码,并且它可以正确运行。如果问题仍然存在,可以尝试添加此标志。感谢@RobertCrovella 和@paleonix 的评论。

© www.soinside.com 2019 - 2024. All rights reserved.