简介:首先,作为介绍,我很自豪地在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) 我正在将一些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) 查看几个视频和文档示例,我们在调用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) 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) 我有一个__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 在不同幅度下具有不同的精度
了解 unicode、语言环境、宽字符和转换对我来说是一次可怕的经历。
我需要读取包含俄语和英语,中国和乌克兰字符的文本文件一次全部
我的方法是以字节块读取文件,然后对块进行操作,在单独的线程上进行快速读取。(关联)
这是使用 std::ifstream.read(myChunkBuffer, chunk_byteSize)
但是,我知道如果我坚持使用char.
就此而言,我将一切都转化wchar_t为最佳状态并希望得到最好的结果。
我也知道Sys.setlocale(locale = "Russian") (链接),但它不是将每个字符解释为俄语吗?当我解析字节时,我不知道何时在我的 4 种语言之间切换。
在 Windows 操作系统上,我可以创建一个 .txt 文件并写上“??????!你好!” 在程序 Notepad++ 中,它将保存文件并以相同的字母重新打开。它是否以某种方式在每个字符后秘密添加隐形标记,以了解何时解释为俄语,何时解释为英语?
我目前的理解是:将所有内容都作为wchar_t(双字节),将任何文件解释为 UTF-16(双字节) - 是否正确?
另外,我希望保持代码跨平台。
对不起菜鸟
我写了一些代码来增加一些对称矩阵,并决定用来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函数.
任何帮助都会很精彩...... :).
我有一个得分变量,它可以在主循环的每次迭代中增长和缩小.
需要获得过去1000秒内的平均分数.(也就是说,我需要一个简单的移动平均线)
计算平均值的最简单方法是保留一个分数列表,与记录分数的时间戳配对.
每一帧,我们遍历列表,并总结score*deltaTime,在哪里deltaTime计算为和(ourTimestamp - prevTimeStamp) / 1000sec.的结果是我们这帧的过去1000秒的平均值.我们将处理列表中的任何旧元素,这些元素的时间戳早于"现在"的1000秒
上述方法将耗费内存.有没有更简单的方法来立即计算平均值,而不保留这个"踪迹列表"?