小编Kar*_*ari的帖子

在CUDA中增加每个线程的工作的示例

简介:首先,作为介绍,我很自豪地在StackOverflow上提出我的第一个问题.我希望我能帮助别人,就像他们帮助我一样.

算法:

我正在用CUDA编写一个程序,问题如下:

  • 两个矩阵A(n*128)和B(m*128)

  • 我取A的第一行,然后逐个计算该向量与B的所有行之间的距离.

  • 我在矩阵C的一行上写出每个距离的结果,因此C的元素C(i,j)包含A的行i和B的行j之间的距离.

  • 然后我继续下一行A.

我用这种方式实现了它:我有一个由(n*m)个块组成的网格,每个块有128个线程.(1*128).

问题:程序成功运行并带有预期结果,但执行时间仅比单线程CPU版本快5到10倍.所以我想知道如何在减少之前增加每个线程的工作量以提高性能.

内核代码(原始:未优化)

 __global__ void EuclideanDistances( float *A, float *B , float *C , int n , int m)
{
    // SIZE is equal to 128
__shared__ float accumResult[SIZE];
float sA;
float sB;

    // MAPPING
int bx = blockIdx.x;  // n
int by = blockIdx.y;  // m
int ty = threadIdx.y; // 128
int tx = threadIdx.x; // 1


sA = A [bx * SIZE + ty];
sB …
Run Code Online (Sandbox Code Playgroud)

c++ cuda euclidean-distance distance-matrix

10
推荐指数
1
解决办法
1320
查看次数

如何在gcc中静态初始化__m128i数组?

我正在将一些SSE优化代码从Windows移植到Linux.我发现以下代码在MSVC中运行良好,在GCC中不起作用.

代码是初始化一个数组__m128i.每个__mi28i包含16个int8_t.它使用gcc编译,但结果不符合预期.

实际上,正如gcc定义的__m128i那样long long int,代码将初始化一个数组,如:

long long int coeffs_ssse3[4] = {64, 83, 64, 36}.

我用谷歌搜索并被告知"初始化矢量的唯一可移植方法是使用_mm_set_XXX内在函数." 但是,我想知道有没有其他方法来初始化__m128i数组?更好的静态,并且不需要修改以下代码(因为我有以下格式的大量代码).任何建议表示赞赏.

static const __m128i coeffs_ssse3[4] =
{
    { 64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0},
    { 83, 0, 36, 0,-36,-1,-83,-1, 83, 0, 36, 0,-36,-1,-83, -1},
    { 64, 0,-64,-1,-64,-1, 64, 0, 64, 0,-64,-1,-64,-1, 64, 0},
    { 36, 0,-83,-1, 83, 0,-36,-1, 36, 0,-83,-1, …
Run Code Online (Sandbox Code Playgroud)

gcc sse initialization

8
推荐指数
1
解决办法
3663
查看次数

在condition_variable::notify_all() 之后或之前解锁互斥锁?

查看几个视频文档示例,我们调用notify_all(). 之后调用会更好吗?

常见的方式:

通知程序线程内部:

//prepare data for several worker-threads;

//and now, awaken the threads:
std::unique_lock<std::mutex> lock2(sharedMutex);
_threadsCanAwaken = true;

lock2.unlock(); 
_conditionVar.notify_all(); //awaken all the worker threads;

//wait until all threads completed;

//cleanup:
_threadsCanAwaken = false;

//prepare new batches once again, etc, etc
Run Code Online (Sandbox Code Playgroud)

在工作线程之一内部:

while(true){
    // wait for the next batch:

    std::unique_lock<std::mutex> lock1(sharedMutex);
    _conditionVar.wait(lock1,  [](){return _threadsCanAwaken});
    lock1.unlock(); //let sibling worker-threads work on their part as well

    //perform the final task

    //signal …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading condition-variable

8
推荐指数
1
解决办法
4403
查看次数

提示编译器浮点向量计数可被8整除吗?

static inline void R1_sub_R0(float *vec,  size_t cnt,  float toSubtract){
    for(size_t i=0; cnt; ++i){
        vec[i] -= toSubtract;
    }
}
Run Code Online (Sandbox Code Playgroud)

我知道cnt它将始终被8整除,因此可以通过SSE和AVX将代码矢量化。换句话说,我们可以*vec作为一个__m256类型进行迭代。但是编译器可能不会知道这一点。如何重新向编译器保证此计数被8整除?

这样的事情会有所帮助吗?(如果我们将其粘贴在函数的开头)

assert(((cnt*sizeof(float)) % sizeof(__m256)) ==0 );  //checks that it's "multiple of __m256 type".
Run Code Online (Sandbox Code Playgroud)

当然,我可以简单地将整个内容编写为矢量化代码:

static inline void R1_sub_R0(float *vec,  size_t cnt,  float toSubtract){
    assert(cnt*sizeof(float) % sizeof(__m256) == 0);//check that it's "multiple of __m256 type".
    assert(((uintptr_t)(const void *)(POINTER)) % (16) == 0);//assert that 'vec' is 16-byte aligned

    __m256 sToSubtract = _mm256_set1_ps(toSubtract);
    __m256 *sPtr = (__m256*)vec; …
Run Code Online (Sandbox Code Playgroud)

c++ vectorization compiler-optimization

5
推荐指数
1
解决办法
102
查看次数

将“__m256 with random-bits”转换为 [0, 1] 范围的浮点值

我有一个__m256包含随机位的值。

我想,以“解释”,就得到另一个__m256保存float 在值均匀 [0.0f, 1.0f]范围。

计划使用:

__m256 randomBits = /* generated random bits, uniformly distribution */;
__m256 invFloatRange =  _mm256_set1_ps( numeric_limits<float>::min() ); //min is a smallest increment of float precision

__m256 float01 =  _mm256_mul(randomBits, invFloatRange);
//float01 is now ready to be used
Run Code Online (Sandbox Code Playgroud)

问题 1:

但是,这会在非常罕见的情况下导致问题,其中randomBits所有位都为 1,因此是 NAN?

我能做些什么来保护自己免受这种伤害?

我希望float01永远是一个可用的数字

问题2:

使用上述方法获得后,[0 到 1] 范围会保持一致吗?我知道 float 在不同幅度下具有不同的精度

c++ random floating-point simd avx

5
推荐指数
1
解决办法
154
查看次数

读取多语言文件 - wchar_t vs char?

了解 unicode、语言环境、宽字符和转换对我来说是一次可怕的经历。

我需要读取包含俄语和英语,中国和乌克兰字符的文本文件一次全部

我的方法是以字节块读取文件,然后对块进行操作,在单独的线程上进行快速读取。(关联)

这是使用 std::ifstream.read(myChunkBuffer, chunk_byteSize)

但是,我知道如果我坚持使用char.


就此而言,我将一切都转化wchar_t为最佳状态并希望得到最好的结果。

我也知道Sys.setlocale(locale = "Russian") (链接),但它不是将每个字符解释为俄语吗?当我解析字节时,我不知道何时在我的 4 种语言之间切换。

在 Windows 操作系统上,我可以创建一个 .txt 文件并写上“??????!你好!” 在程序 Notepad++ 中,它将保存文件并以相同的字母重新打开。它是否以某种方式在每个字符后秘密添加隐形标记,以了解何时解释为俄语,何时解释为英语?


我目前的理解是:将所有内容都作为wchar_t(双字节),将任何文件解释为 UTF-16(双字节) - 是否正确?

另外,我希望保持代码跨平台。

对不起菜鸟

c++

3
推荐指数
1
解决办法
1883
查看次数

Cublas Library的链接器问题(无法打开文件'cublas.lib')

我写了一些代码来增加一些对称矩阵,并决定用来CUDA (cublasSgemm)为我做这项工作.

我有工具包,以及其他所有设置但在我尝试使用这些cublas功能时遇到问题.

我已经包括:

#include <cuda_runtime.h>
#include "cublas_v2.h"
Run Code Online (Sandbox Code Playgroud)

我还去了Properties> Linker> Input并添加cublas.lib到依赖项中.当我把所有事情都推进时,我遇到了这个错误:

LINK : fatal error LNK1104: cannot open file 'cublas.lib'
Run Code Online (Sandbox Code Playgroud)

如果我从依赖项中删除库,我将获得unsolved errors所有cublas函数.

任何帮助都会很精彩...... :).

linker cuda visual-studio-2012

1
推荐指数
1
解决办法
2644
查看次数

过去1000秒内立即平均值

我有一个得分变量,它可以在主循环的每次迭代中增长和缩小.

需要获得过去1000秒内的平均分数.(也就是说,我需要一个简单的移动平均线)

这个问题是相关的,但我不想跟踪前一帧的任何得分值.

计算平均值的最简单方法是保留一个分数列表,与记录分数的时间戳配对.

每一帧,我们遍历列表,并总结score*deltaTime,在哪里deltaTime计算为和(ourTimestamp - prevTimeStamp) / 1000sec.的结果是我们这帧的过去1000秒的平均值.我们将处理列表中的任何旧元素,这些元素的时间戳早于"现在"的1000秒

上述方法将耗费内存.有没有更简单的方法来立即计算平均值,而不保留这个"踪迹列表"?

c# average

-1
推荐指数
1
解决办法
264
查看次数